gpt4 book ai didi

python - 为什么这个类中的列表理解对某些方法有效而不对其他方法有效?

转载 作者:行者123 更新时间:2023-12-04 07:17:53 25 4
gpt4 key购买 nike

我是一名研究科学家,正在编写我正在调用的自定义类 MyList()在 Python 3.7 中,旨在添加一些用于列表类型对象的附加方法。我希望这些方法能够就地修改列表对象,而不必重新定义它或将其分配给新的对象名称。例如,假设我已经声明了 foo = MyList()并用一些任意数据填充它。 我的目标是能够做这样的事情:

>>> foo
[1, 1, '', 3, [2, 4, '', 4, 5], [], [6] ]

>>> type(foo)
__main__.MyList

>>> foo.flatten_the_list()

>>> foo.remove_empty_items_from_list()

>>> foo.remove_duplicate_items_from_list()

>>> foo.convert_to_list_items_to_strings()

>>> foo
['1', '2', '3', '4', '5', '6']
我已经在下面发布了我的代码,到目前为止,一些方法工作正常。我集中在从列表对象中删除空项目,从列表对象中的项目中删除空格,并将列表对象中的重复项目删除到一个名为 MyList.cleanup() 的方法中。效果很好。
然而,同样适用于 的列表推导式 MyList.cleanup() , 不适用于展平列表,也不适用于将列表中每个项目的类型从整数转换为字符串。到目前为止我的代码:
class MyList(list):

# No def __init__() statement needed - inherits from list object

# MyList.convert_v2() WORKS without list comprehension
def convert_v2(self, dtype):
for i in range(len(self)):
self[i] = str(self[i])
return self

# MyList.convert_v1() DOESN'T WORK with list comprehension
def convert_v1(self, dtype):
self = [str(item) for item in self]
return self

# MyList.cleanup() WORKS with list comprehension
def cleanup(self):
# Remove empty items
self = [item for item in self if "" is not item]
# Remove duplicate items
self = list(dict.fromkeys(self))
# Remove whitespace (including \t and \n)
self = ["".join(str(item).split()) for item in self]
return self

# MyList.flatten() DOESN'T WORK with list comprehension
def flatten(self):
self = [item for sublist in self for item in sublist]
return self
这是我使用 MyList.convert_v1() 方法时得到的结果(我第一次尝试将列表内容转换为字符串的方法):
>>> bar
[1, 2, 3, 4, 5, 6]

>>> type(bar[0])
int

>>> bar.convert_v1()
['1', '2', '3', '4', '5', '6']

>>> bar
[1, 2, 3, 4, 5, 6]

>>> type(bar[0])
int
但是,我不得不停止使用列表理解来通过 MyList.convert_v2() 获得所需的效果:
>>> bar
[1, 2, 3, 4, 5, 6]

>>> type(bar[0])
int

>>> bar.convert_v2()
['1', '2', '3', '4', '5', '6']

>>> bar
['1', '2', '3', '4', '5', '6']

>>> type(bar[0])
str
为什么 MyList.convert_v2() 按预期工作,当 MyList.convert_v1() 才不是?在类之外,我不希望这两个函数的行为不同,但在类内,它们的行为确实不同。
同样,这就是我从 MyList.flatten() 方法中得到的:
>>> baz
[[1, 2, 3, 4], [5, 6, 7, 8]]

>>> baz.flatten()
[1, 2, 3, 4, 5, 6, 7, 8]

>>> baz
[[1, 2, 3, 4], [5, 6, 7, 8]]
虽然所需的结果如图所示打印到输出中,但列表对象 baz实际上并没有被压平。调用该方法后,列表保持不变。我需要它来代替:
>>> baz
[[1, 2, 3, 4], [5, 6, 7, 8]]

>>> baz.flatten()
[1, 2, 3, 4, 5, 6, 7, 8]

>>> baz
[1, 2, 3, 4, 5, 6, 7, 8]
为什么列表理解在 中工作得很好 MyList.cleanup() 方法,但不在 MyList.convert() MyList.flatten() 方法? 我认识到我是 OOP 和编写类(class)的新手,所以如果我在这里完全偏离基础,我期待学习我可以做的不同的事情。

最佳答案

根据 @jasonharper的评论,使用 self =没有完成任何事情,所以要覆盖整个列表,只需使用 self[:] .
对于扁平列表,this answer使用带有递归的生成器,以便仍然可以展平未知深度的列表。

结合上述两者来完成您在第一个示例中想要的内容可能如下所示:

from collections.abc import Iterable
from re import sub


class MyList(list):
def _flattener(self, _list):
"""Generator used to flatten lists of undefined depth."""
for el in _list:
if isinstance(el, Iterable) and not isinstance(el, (str, bytes)):
yield from self._flattener(el)
else:
yield el

def flatten(self):
self[:] = self._flattener(self)
return self

def remove_empty(self):
self[:] = [item for item in self if item or item == 0]
return self

def convert_to_strings(self):
self[:] = list(map(str, self))
return self

def remove_duplicates(self):
self[:] = list(dict.fromkeys(self))
return self

def remove_whitespace(self):
self.convert_to_strings()
self[:] = [sub(r"\s+", "", item) for item in self]
return self

输出
>>> bar = MyList()
>>> bar.extend([0, 1, 1, "", 3, [2, 4, "", 4, 5], [], None, {}, [6], "Hello\n World"])

>>> bar.flatten()
>>> bar.remove_empty()
>>> bar.convert_to_strings()
>>> bar.remove_duplicates()
>>> bar.remove_whitespace()
>>> bar
['0', '1', '3', '2', '4', '5', '6', 'HelloWorld']

关于python - 为什么这个类中的列表理解对某些方法有效而不对其他方法有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68688377/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com