【问题标题】:Python: How to pass list as a parameter to a function? [duplicate]Python:如何将列表作为参数传递给函数? [复制]
【发布时间】:2016-04-22 16:35:51
【问题描述】:

我刚开始使用 Python,并且正在使用以下代码将 CSV 文件导入到 sqlite3 表中,我承认我已经从互联网上复制了大部分内容:

with open(getPathTo('my.csv'), 'r') as csvfile:
  reader = csv.DictReader(csvfile)
  records = [(row['SEGMENT'], row['Comp 1'], row['Comp 2']) for row in reader]
c.executemany("INSERT INTO comparison (`SEGMENT`, `Comp 1`, `Comp 2`) VALUES (?,?,?);", records)
conn.commit()

它工作正常,但我对很多文件和表重复这个,我想把它变成一个函数。我的目标是:

def importCSVToTable(file, table, columns)

但是,给定columns 的列表,我该如何在这一行中使用它:

records = [(row['SEGMENT'], row['Comp 1'], row['Comp 2']) for row in reader]

我想我只是对语法有点失望。

【问题讨论】:

  • 每个表的列数和名称是否变化?
  • 是的。不同的表,具有不同的架构。
  • 你考虑过sqlalchemy ORM吗?谢谢。
  • 还没有。对于一个快速的 python 脚本来批处理一些 CSV 文件,ORM 似乎有点矫枉过正,但如果没有其他工作,我会试一试。谢谢。

标签: python csv


【解决方案1】:

这里有一些示例代码,展示了一些可能有用的东西。我们使用带有过滤if 语句的嵌套理解来确保我们不会尝试访问不存在的dict 项。

In [3]: def importCSVtoTable(file, table, columns):
   ...:     # 'mock' data to simulate a reader
   ...:     reader = [{'SEGMENT': 2, 'Comp 1': 'dogs'}, {'Comp 2': 'cats', 'OTHERTHING': 4}
   ...:     print [[row[label] for label in columns if label in row] for row in reader]
   ...:

In [4]: importCSVtoTable(None, None, ['SEGMENT', 'Comp 1'])
[[2, 'dogs'], []]

In [5]: importCSVtoTable(None, None, ['SEGMENT', 'Comp 1', 'Comp 2'])
[[2, 'dogs'], ['cats']]

【讨论】:

  • 这正是我在回答中所解释的。 +1
  • 这正是我想要的,谢谢!
【解决方案2】:

所以我认为您要问的是,给定一个键(列)列表,我如何从字典中提取它们?让我们使用内存中的 CSV 文件来测试一下:

>>> example_data = """col1,col2,col3\na1,a2,a3\nb1,b2,b3\nc1,c2c3"""
>>> print example_data
col1,col2,col
a1,a2,a3
b1,b2,b3
c1,c2c3

那么,如果我们有一个基于它的 csvreader:

>>> import csv, StringIO
>>> reader = csv.DictReader(StringIO.StringIO(example_data))
>>> print reader.fieldnames
['col1', 'col2', 'col3'] 

所以,如果我们想基于该字段列表进行迭代:

>>> for row in reader:
...     print 'insert into mytable (%s) values (%s)' % (','.join(reader.fieldnames), ','.join(['?']*len(reader.fieldnames)))
insert into mytable (col1,col2,col3) values (?,?,?)
insert into mytable (col1,col2,col3) values (?,?,?)
insert into mytable (col1,col2,col3) values (?,?,?)

显然,您需要根据自己的功能对其进行调整。但这是否回答了您关于 csvreader 机制和操作 Python 列表的问题?

(注意,这是针对 Python 2 的。)

【讨论】:

  • 这不是我想要的——我想看看我是否可以修改现有代码中的一行来处理列表——但它确实很有用,谢谢。
【解决方案3】:

也许是这样的?当然未经测试。

def importCSVToTable(conn, filename, table, columns)
    with open(getPathTo(filename), 'r') as csvfile:
        reader = csv.DictReader(csvfile)
        records = []
        for row in reader:
            for col in columns:
                records.append(row[col])
    conn.executemany("INSERT INTO comparison (" + ','.join(columns) + ") VALUES ("+ ','.join(["?"]*columns.length) +");", records)
    conn.commit()

【讨论】:

  • 是的,可以这样做,但我想要一种方法可以在一条线上完成所有操作,就像上面的答案一样。
  • @Wintermute k。但我觉得,虽然可能非常 Pythonic,但将如此多的信息和控制流塞进一行并不是很容易维护。但我猜每个人都有自己的
【解决方案4】:

在函数中获取列列表,然后为列表中的每个元素找到row[list-element] 并附加到列表以进行记录。

【讨论】:

  • 这会得到所有的列;他似乎希望能够选择从 CSV 中提取哪些内容。
  • 不,我认为他想拉所有列。
  • 不,我想选择哪些被拉取,如columns 列表中指定的那样,我将传递给函数。我正在努力解决的是如何将该列列表传递到填充 records 变量的行中
  • @Wintermute 然后只需将列名作为['a','b','c'] 之类的列表传递,并在我所说的函数中使用a for each 来查找row[list-element]
  • 为什么投反对票? @AP 为我的解释提供了代码。
猜你喜欢
  • 2015-06-06
  • 2014-02-15
  • 1970-01-01
  • 2012-03-07
  • 2021-11-03
  • 2019-09-09
  • 1970-01-01
  • 1970-01-01
  • 2014-12-17
相关资源
最近更新 更多