在Python中使用filter函数

1 投票
2 回答
1975 浏览
提问于 2025-04-17 07:12

我想用Python自带的filter函数来从CSV文件的某些列中提取数据。这样使用filter函数合适吗?我需要先定义这些列里的数据吗,还是说Python会自动知道哪些列包含什么数据?

2 个回答

7

因为Python自带了很多功能,所以在日常使用中,很多情况已经有人提供了解决方案。

CSV就是其中之一,Python有一个内置的csv模块可以使用。

另外,tablib是一个非常不错的第三方模块,特别适合处理非ASCII数据。

对于你在评论中描述的行为,可以使用以下代码:

import csv
with open('some.csv', 'rb') as f:
   reader = csv.reader(f)
   for row in reader:
      row.pop(1)
      print ", ".join(row)
2

filter函数的主要作用是从一个列表(或者一般来说,任何可迭代的对象)中挑选出符合特定条件的元素。它并不是用来根据索引来选择的。因此,虽然你可以用它来挑选CSV文件中的特定列,但我不太推荐这样做。你可能更应该使用类似下面的方式:

with open(filename, 'rb') as f:
    for record in csv.reader(f):
        do_something_with(record[0], record[2])

根据你对记录的具体操作,创建一个只关注你需要的列的迭代器可能会更好:

with open(filename, 'rb') as f:
    the_iterator = ((record[0], record[2]) for record in csv.reader(f))
    # do something with the iterator

或者,如果你需要非顺序处理,可能还可以使用一个列表:

with open(filename, 'rb') as f:
    the_list = [(record[0], record[2]) for record in csv.reader(f)]
    # do something with the list

我不太明白你说的“定义列中的数据”是什么意思。数据是由CSV文件定义的。


相比之下,有一种情况是你确实想用filter的:假设你的CSV文件包含数字数据,而你需要建立一个列表,里面的记录是行内数字严格递增的。你可以写一个函数来判断一组数字是否是严格递增的:

def strictly_increasing(fields):
    return all(int(i) < int(j) for i,j in pairwise(fields))

(可以查看itertools文档来了解pairwise的定义)。然后你可以把这个作为filter中的条件:

with open(filename, 'rb') as f:
    the_list = filter(strictly_increasing, csv.reader(f))
    # do something with the list

当然,同样的功能通常可以用列表推导式来实现:

with open(filename, 'rb') as f:
    the_list = [record for record in csv.reader(f) if strictly_increasing(record)]
    # do something with the list

所以在实际应用中,使用filter的理由并不多。

撰写回答