试图过滤项目集

时间:2018-02-16 22:34:56

标签: python parsing tuples

我有一个名为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

尽管如此,当我尝试运行上面的代码时,我最终得到一个空列表,但我已经通过变量检查器查看了列表,并且我已经看到 出现了这个,但过滤后它们不会显示出来。怎么了?

4 个答案:

答案 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 fasterSpeed of list comprehension vs for loop with appendEfficiency of list comprehensionsAre these list-comprehensions written the fastest possible way?

<强>其次:  代码可读性。 list comprehensions语法是一种更紧凑的方式,因此更容易阅读,这使它更“pythonic”。 List Comprehensions Explained Visually

顺便说一下:即使在迭代时修改序列也是个好主意,在大多数情况下,分别保留输入(原始)和输出(处理过的)数据集非常方便,并且允许派生多个进一步的输出(通过过滤不同的条件)。用处理/过滤替换原始数据使得对过滤条件的进一步改变变得不可能,另一方面,当处理输入数据非常耗费时间和/或资源时(或者,如果它绝对确定不需要原始数据集),它有时是有利的。了)。

进一步阅读:(效果优化和陷阱):Generators or List comprehensionsBeware 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)]