【问题标题】:Use For loop in an If statement在 If 语句中使用 For 循环
【发布时间】:2015-04-20 08:22:18
【问题描述】:

问题

我有一个由 380 行和 20 列组成的表格。我想根据特定条件从该表中删除行。

为了澄清事情,假设我有清单:

names = ['John', 'Amy', 'Daniel']

我想删除所有在列表names中找到姓名的人的数据。

例如,假设我的数据如下所示:

John    82    3.12    boy
Katy    12    1.12    girl
Amy     42    2.45    girl
Robert  32    1.56    boy
Daniel  47    2.10    boy

我想删除JohnAmyDaniel的数据。所以输出应该是:

Katy    12    1.12    girl
Robert  32    1.56    boy

尝试解决

import csv
import numpy as np

# loading data
data = np.genfromtxt('file.txt', dtype = None)

csvfile = "home/paula/Desktop/test.txt"
with open(csvfile, 'w') as output:
    writer = csv.writer(output, delimiter = '\t')

    for row in range(len(data)):
        if data[row][0] == (i for i in names):
            print 'removing the data of', i, '...'
        else:
            writer.writerow([data[row][0], data[row][1], 
                             data[row][2], data[row][3]])

我的代码正在运行,但数据并未从我的原始数据中删除。当我打开新的test.txt文件时,可以看到数据没有被删除。

我确定错误在if data[row][0] == (i for i in names): 我该如何解决这个问题?

【问题讨论】:

  • data 是什么?你在哪里定义它?
  • @MrE,我没有错误,脚本工作正常。但是当我检查输出时,test.txt 文件,我可以看到我仍然有相同的数据。
  • @RafaelCardoso,我编辑了问题,我正在使用np.genfromtxt加载数据

标签: python if-statement for-loop


【解决方案1】:

条件应该写成:

if data[row][0] in names:

在您当前的代码中,(i for i in names) 创建了一个生成器,然后您正在测试字符串是否等于生成器对象,这将是错误的

>>> (i for i in names)
<generator object <genexpr> at 0x1060564b0>
>>> 'John' == (i for i in names)
False
>>>

相反,您可以测试一个项目是否在列表中,如下所示

>>> names = ['John', 'Amy', 'Daniel']
>>> 'John' in names
True
>>> 'Bob' in names
False
>>>

如 cmets 中所述,您可以通过在遍历行之前将 names 转换为 set 来提高此检查的效率。但理想情况下,您将使用 Pandas 库来操作 csv/table 数据。有关类似示例,请参阅 this answer。您可以使用df[~df.Name.isin(...)] 否定条件。

【讨论】:

  • 将名称设为一组会更有效率
  • 会,但我想尽可能简洁地解释当前方法的问题。我添加了指向 Pandas 的链接,这将比使用 set 的任何手工代码更有效。我会补充几句。
  • 如果有更好的代码编写方法,我将不胜感激。特别是我对最后一行不满意:writer.writerow([ ... ])。正如我上面所说,我的数据由 20 列组成,所以在 writer.writerow 中我必须写 20 列!非常感谢!
【解决方案2】:

您正在检查data[row][0] 是否与(i for i in names) 相同。您要做的是检查它是否与(i for i in names)元素 之一相同。你可以这样做:

any([data[row][0]==i for i in names])

您也可以使用in 运算符以非荒谬的方式进行操作:

data[row][0] in names

这会检查names 的任何元素是否与data[row][0] 相同。

【讨论】:

    【解决方案3】:
    if data[row][0] == (i for i in names):
                print 'removing the data of', i, '...'
    

    在那部分i(i for i in names) 中用作本地验证。但在下一个打印行中,您使用i。这里不能用这个。

    您可以使用if data[row][0] in names: 进行检查。你可以试试:

    if data[row][0] ==  names:
                print 'removing the data of', data[row][0], '...'
    

    【讨论】:

      猜你喜欢
      • 2014-03-13
      • 2017-06-02
      • 2013-08-26
      • 2014-08-25
      • 2013-05-28
      • 1970-01-01
      • 1970-01-01
      • 2023-01-13
      相关资源
      最近更新 更多