从每个子列表中删除特定位置的元素

时间:2018-03-06 10:29:07

标签: python list list-comprehension

我有一个列表,例如:

a = [[1,'b',2],[3,':',4],[5,':',6]]

我想删除' b'和':'字符,所以我最终得到:

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

(请注意,这些字符位于每个子列表的第二个位置这一事实只是我选择的一个例子 - 我正在处理的真实数据集在随机位置具有相同的字符。)

我选择使用列表理解来执行此操作。以下是迭代子列表中每个项目的代码示例:

for list in a:
    for number in list:
        print number

但是当我实现我的列表理解而不是像这样的print语句时:

b = []

for list in a:
    for number in list:
        b = [number for number in list if number != 'b' and number != ':']
        print b

我得到以下输出:

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

我的问题是,为什么每个子列表有三个副本?我在期待

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

非常感谢任何帮助和/或指导。

干杯。

5 个答案:

答案 0 :(得分:5)

如果您尝试删除的所有内容都是b:,则可以使用嵌套列表理解和设置成员资格测试:

a_new = [[y for y in x if y not in {'b', ':'}] for x in a]

但是,如果您想要将其概括为删除任何非数字元素,请使用isinstance检查进行过滤:

import numbers
a_new = [[y for y in x if isinstance(y, numbers.Number)] for x in a]

请注意,这与:

相同
a_new = []
for i in a:
    a_new.append([])
    for j in i:
        if isinstance(j, numbers.Number):
            a_new[-1].append(j)

请注意,这里只需要2个循环(您的代码有3个,这就是为什么所有内容都被复制3次 - 每个内部列表中的项目数!)。

print(a_new)
[[1, 2], [3, 4], [5, 6]]

此处另一个注意事项,numbers.Number任何数值的注入超类(包括无理值)。如果您的用例不包含复数,您可能希望使用numbers.Rationalnumbers.Real

最后提示,如上所述here,请不要使用list / dict其他此类名称作为变量,它们最终会影响实际的内置组件。

答案 1 :(得分:0)

试试这个

d=[[number2 for number2 in number if number2 != 'b' and number2 != ':'] for number in a ]

输出:

  

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

答案 2 :(得分:0)

这似乎是XY problem。以下是一些选项,具体取决于您 希望做什么。

仅包含数字类型和返回列表

arr = [[1,'b',2], [3,':',4], [5,':',6]]

def is_num(x):
    return isinstance(x, (int, float))

arr = [[i for i in k if is_num(i)] for k in arr]

# [[1, 2], [3, 4], [5, 6]]

仅排除'b'和':'字符并返回列表

See @Coldspeed's solution.

答案 3 :(得分:0)

我也会列表理解,但这里有del的变体。

lst = [[1,'b',2],[3,':',4],[5,':',6]]

for x in lst:
    for idx, y in enumerate(x):
        if y in {'b', ':'}:
            del x[idx]
            break

当然,这仅在只有一个特殊字符的情况下才有效。否则,您需要向后迭代子列表。

答案 4 :(得分:-1)

只需创建更多功能,使所有内容更具可读性:

INVALID_ENTRIES = {':', 'b'}

def is_relevant_entry(entry):
    return entry not in INVALID_ENTRIES

def clean_item(item):
    return list(filter(is_relevant_entry, item))

def clean_list(lst):
    return list(map(clean_item, lst))

a = [[1,'b',2],[3,':',4],[5,':',6]]
result = clean_list(a)

我认为它比这些理解的单行更好。

没有循环,名称传达标准库的含义和用法:)

在python2中mapfilter非常渴望,所以你不需要用list

包裹