我有一个名为data
的项目集,其中每个项目集都是元组的第一个元素。一个实例的示例如下所示:
(('5', 'Generous', '<=X'), 0.33333333333333)
我试图通过两个部分来过滤项目集:
第1部分 - 我试图过滤掉项目集,以便剩下的唯一实例是在实际项目集中包含'&lt; = X'的实例(在每个实例的元组的第一部分内)。
第1部分的代码:
for i in data:
if "<=X" not in i[0]:
del i
第2部分 - 我现在正在尝试获取其余项目并对其进行过滤,以便剩下的唯一集合是项目集中有三个或更多项目的项目。
第2部分的代码:
for i in data:
if len(i[0]) < 3:
del i
尽管如此,当我尝试运行上面的代码时,我最终得到一个空列表,但我已经通过变量检查器查看了列表,并且我已经看到 出现了这个,但过滤后它们不会显示出来。怎么了?
答案 0 :(得分:1)
希望这适合你:
list(filter(lambda x: len(x[0]) >= 3, filter(lambda x: '<=X' in x[0], lst)))
或结合两个条件:
list(filter(lambda x: len(x[0]) >= 3 and '<=X' in x[0], lst))
另外,请注意你的循环中的del
实际上没有做你想让他们完成的事情:
In [175]: data = [1, 2, 3, 4]
In [176]: for k in data:
...: del k
...:
In [177]: data
Out[177]: [1, 2, 3, 4]
此外,在循环时修改列表是一个坏主意。
In [183]: lst = [(('5', 'Generous', '<=X'), 0.33333333333333),
...:(('Generous', '<=X'), 0.33333333333333)]
In [184]: list(filter(lambda x: len(x[0]) < 3, filter(lambda x: '<=X' in x[0], lst)))
Out[184]: [(('Generous', '<=X'), 0.33333333333333)]
答案 1 :(得分:1)
>>> part_1_data = [
... (('5', 'Generous', '<=X'), 0.33333333333333),
... (('6', 'Generous', '<=Y'), 0.33333333333333),
... (('7', 'Generous', '<=Z'), 0.33333333333333)
... ]
>>> part_1 = [elem for elem in part_1_data if '<=X' in elem[0]]
>>> part_1
[(('5', 'Generous', '<=X'), 0.33333333333333)]
>>> part_2_data = [
... (('5', 'Generous', '<=X'), 0.33333333333333),
... (('6', 'Generous'), 0.33333333333333),
... (('7',), 0.33333333333333)
... ]
>>> part_2 = [elem for elem in part_2_data if len(elem[0]) >= 3]
>>> part_2
[(('5', 'Generous', '<=X'), 0.33333333333333)]
>>> both = [
... (('1', 'Generous', '<=X', 4), 0.33333333333333),
... (('2', 'Generous', '<=Y'), 0.33333333333333),
... (('3', 'Generous', '<=Z'), 0.33333333333333),
... (('4', 'Generous', '<=X'), 0.33333333333333),
... (('5', 'Generous'), 0.33333333333333),
... (('6',), 0.33333333333333)
... ]
>>> [elem for elem in both if len(elem[0]) >= 3 and '<=X' in elem[0]]
[(('1', 'Generous', '<=X', 4), 0.33333333333333), (('4', 'Generous', '<=X'), 0.33333333333333)]
答案 2 :(得分:0)
在Python3中,您可以在列表解析中使用解包:
s = [(('5', 'Generous', '<=X'), 0.33333333333333)]
final_results = [((*b, c), a) for (*b, c), a in s if len(b)+1 >=3 and c == '<=X']
答案 3 :(得分:0)
您正在尝试在迭代时修改序列。有关详细信息,请参阅Remove items from a list while iterating。
IMO你应该考虑使用列表推导,它比你当前的方法有很多优点。
首先:表现。 list comprehensions are significantly faster,Speed of list comprehension vs for loop with append,Efficiency of list comprehensions,Are these list-comprehensions written the fastest possible way?。
<强>其次:强> 代码可读性。 list comprehensions语法是一种更紧凑的方式,因此更容易阅读,这使它更“pythonic”。 List Comprehensions Explained Visually
顺便说一下:即使在迭代时修改序列也是个好主意,在大多数情况下,分别保留输入(原始)和输出(处理过的)数据集非常方便,并且允许派生多个进一步的输出(通过过滤不同的条件)。用处理/过滤替换原始数据使得对过滤条件的进一步改变变得不可能,另一方面,当处理输入数据非常耗费时间和/或资源时(或者,如果它绝对确定不需要原始数据集),它有时是有利的。了)。
进一步阅读:(效果优化和陷阱):Generators or List comprehensions,Beware the Python generators
快速简单(虽然有点脏)解决方案,用于过滤您问题中描述的数据结构:
In [1]: dat = [(('1', 'Generous', '<=X', 4), 0.33333333333333),
...: (('2', 'Generous', '<=Y'), 0.33333333333333),
...: (('3', 'Generous', '<=Z'), 0.33333333333333),
...: (('4', 'Generous', '<=X'), 0.33333333333333),
...: (('5', 'Generous'), 0.33333333333333),
...: (('6',), 0.33333333333333)]
...:
...: result = [itm for itm in dat if ('<=X' in itm[0]) and (len(itm[0]) >= 3)]
In [2]: dat
Out[2]:
[(('1', 'Generous', '<=X', 4), 0.33333333333333),
(('2', 'Generous', '<=Y'), 0.33333333333333),
(('3', 'Generous', '<=Z'), 0.33333333333333),
(('4', 'Generous', '<=X'), 0.33333333333333),
(('5', 'Generous'), 0.33333333333333),
(('6',), 0.33333333333333)]
In [3]: result
Out[3]:
[(('1', 'Generous', '<=X', 4), 0.33333333333333),
(('4', 'Generous', '<=X'), 0.33333333333333)]