关于游标:如何将元组的元组转换为一行列表(pythonic)?

How do I convert tuple of tuples to list in one line (pythonic)?

1
2
3
4
5
6
query = 'select mydata from mytable'
cursor.execute(query)
myoutput = cursor.fetchall()
print myoutput

(('aa',), ('bb',), ('cc',))

为什么它(cursor.fetchall)返回元组而不是元组,因为我的查询只要求一列数据?

将其转换为['aa', 'bb', 'cc']的最佳方法是什么?

我可以这样做:

1
2
3
4
mylist = []
myoutput = list(myoutput)
for each in myoutput:
   mylist.append(each[0])

我相信这不是最好的方法。请启发我!


这同样有效:

1
2
3
4
>>> tu = (('aa',), ('bb',), ('cc',))
>>> import itertools
>>> list(itertools.chain(*tu))
['aa', 'bb', 'cc']

编辑Could you please comment on the cost tradeoff? (for loop and itertools)

Itertools速度明显更快:

1
2
3
4
5
6
>>> t = timeit.Timer(stmt="itertools.chain(*(('aa',), ('bb',), ('cc',)))")
>>> print t.timeit()
0.341422080994
>>> t = timeit.Timer(stmt="[a[0] for a in (('aa',), ('bb',), ('cc',))]")
>>> print t.timeit()
0.575773954391

编辑2 Could you pl explain itertools.chain(*)

*将序列解包成位置参数,在本例中是一个嵌套的元组。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> def f(*args):
...    print"len args:",len(args)
...    for a in args:
...       print a
...
>>> tu = (('aa',), ('bb',), ('cc',))
>>> f(tu)
len args: 1
(('aa',), ('bb',), ('cc',))
>>> f(*tu)
len args: 3
('aa',)
('bb',)
('cc',)

另一个例子:

1
2
3
4
5
6
7
8
9
10
>>> f('abcde')
len args: 1
abcde
>>> f(*'abcde')
len args: 5
a
b
c
d
e

请参阅有关解包的文档。


你可以的

1
2
3
4
>>> tup = (('aa',), ('bb',), ('cc',))
>>> lst = [a[0] for a in tup]
>>> lst
['aa', 'bb', 'cc']


Why is cursor.fetchall() returning a tuple of tuples instead of a tuple since my query is asking for only one column of data?

外部元组是完整的结果;每个内部元组表示该结果中的一条记录;因为您只要求一个字段,所以每个内部元组只有一个元素。

What is the best way of converting it to ['aa', 'bb', 'cc'] ?

有几种方法,哪一种最好取决于你在做什么…

简单列表理解:

1
mylist = [each[0] for each in myoutput]

简单生成器(节省内存使用量):

1
2
3
mygen = (each[0] for each in myoutput)
for result in mygen:
    print result

如果您只需要处理myoutput中的项目,也可以

1
2
for each, in myoutput:
    print each

如果您已经对代码进行了分析,发现这是一个瓶颈,那么您可以选择可读性较低但速度较快的代码:

1
2
import itertools
mylist = list(itertools.chain(*myoutput))

或者,如果您只需要处理它:

1
2
3
import itertools
for result in itertools.chain(*myoutput):
    print result


你所做的是正确的,但更简洁,可能表现得更好

1
2
>>> [item for item, in (('aa',), ('bb',), ('cc',)) ]
['aa', 'bb', 'cc']

或者如果你讨厌for关键字,你可以使用map

1
2
>>> map(lambda a:a[0], (('aa',), ('bb',), ('cc',)) )
['aa', 'bb', 'cc']

还有另一种方法

1
2
>>> reduce(lambda a, b:a+b, (('aa',), ('bb',), ('cc',)) )
('aa', 'bb', 'cc')

虽然IMO列表理解是最易读的


这项工作:

1
2
3
>>> tups=(('aa',), ('bb',), ('cc',))
>>> list(*(zip(*tups)))
['aa', 'bb', 'cc']

说明:

1
2
3
4
1) *tups unpacks the nested tuples  ('aa'),('bb'),('cc')
2) zip produces a list of a single tuple with all the elements: [('aa','bb','cc')]
3) * unpacks that  into  'aa', 'bb', 'cc'
4) creates a list from that unpacking.

你也可以这样做:

1
2
>>> list(zip(*tups)[0])
['aa', 'bb', 'cc']


做这样的清单理解:

1
mylist = [ x[0] for x in myoutput ]