2013-03-06 92 views
0

我有數據的元組的列表:如何使用python壓扁元組中的項目列表?

data = [('Date', 'Type', 'Product'), 
     ('2013/03/07', 'Electronic', 'TV, Radio, Microwave'), 
     ('2013/03/07', 'leather', 'Gucci Wallet')] 

我想複製,使我的數據列表這樣簡單:

data = [('Date', 'Type', 'Product'), 
     ('2013/03/07', 'Electronic', 'TV'), 
     ('2013/03/07', 'Electronic', 'Radio'), 
     ('2013/03/07', 'Electronic', 'Microwave'), 
     ('2013/03/07', 'leather', 'Gucci Wallet')] 

請幫我做這個。

+0

我試圖嵌套'爲'循環來解決這個問題,但無法做到這一點! :( – MHS 2013-03-06 06:33:33

回答

4

一個很好的問題,利用itertools。

閱讀解決方案爲拼合對與分裂生成項的列表 ''

list(chain(*(product(*imap(str.split, e)) for e in data))) 

這裏是展示從OP

>>> from pprint import PrettyPrinter 
>>> pp = PrettyPrinter(indent = 4) 
>>> data = [('Date', 'Type', 'Product'), 
     ('2013/03/07', 'Electronic', 'TV, Radio, Microwave'), 
     ('2013/03/07', 'leather', 'Gucci Wallet')] 
>>> from itertools import izip, imap, product, chain 
>>> data = list(chain(*(product(*imap(str.split, e)) for e in data))) 
>>> pp.pprint(data) 
[ ('Date', 'Type', 'Product'), 
    ('2013/03/07', 'Electronic', 'TV,'), 
    ('2013/03/07', 'Electronic', 'Radio,'), 
    ('2013/03/07', 'Electronic', 'Microwave'), 
    ('2013/03/07', 'leather', 'Gucci'), 
    ('2013/03/07', 'leather', 'Wallet')] 

更新 ​​

選項1:

>>> from operator import methodcaller 
>>> list(chain(*(product(*imap(methodcaller("split", ","), e)) for e in data))) 

選項2:

>>> list(chain(*(product(*(s.split(",") for s in e)) for e in data))) 
+0

data = list(chain(*(product(* imap(str.split(','),e))for e in refined_data))),我使用這一行來展平我的代碼,但是它顯示了這個錯誤: 「*之後的類型對象參數必須是一個序列,而不是生成器」,簡單的分割即使用空格和任何特殊字符也可以打破所有的單詞,請幫助我...... – MHS 2013-03-07 06:45:23

+0

@RoBErT:查看更新後的答案 – Abhijit 2013-03-07 07:58:43

0

此代碼應該可以幫助您使數據更簡單。

data = [('Date', 'Type', 'Product'), ('2013/03/07', 'Electronic', 'TV, Radio, Microwave'), ('2013/03/07', 'leather', 'Gucci Wallet')] 

for tup in data: 
    items=tup[2].split(','); 
    if len(items)>1: 
     date=tup[0]; 
     typ=tup[1]; 
     data.remove(tup); 
     for i in items: 
      data.append(tuple([date,typ,i])); 

PS:這可能無法保持原來的順序。

1

因爲第三元素是一個逗號分隔的字符串,你可以檢查它的存在和分裂相應

In [131]: data 
Out[131]: 
[('Date', 'Type', 'Product'), 
('2013/03/07', 'Electronic', 'TV, Radio, Microwave'), 
('2013/03/07', 'leather', 'Gucci Wallet')] 

In [132]: data2 = [] 

In [133]: for item in data: 
    .....:  if item[2].find(',') > -1: 
    .....:   x = [(item[0], item[1], x.strip()) for x in item[2].split(',')] 
    .....:   for i in x: 
    .....:    data2.append(i) 
    .....:  else: 
    .....:   data2.append(item) 
    .....: 

In [134]: data2 
Out[134]: 
[('Date', 'Type', 'Product'), 
('2013/03/07', 'Electronic', 'TV'), 
('2013/03/07', 'Electronic', 'Radio'), 
('2013/03/07', 'Electronic', 'Microwave'), 
('2013/03/07', 'leather', 'Gucci Wallet')] 
0

我想這樣做的方法是

def mycopy(lst): 
    newlst = [] 
    for tup in lst: 
     newitems = tup[-1].split(',') 
     rest = tup[:-1] 
     for i in newitems: 
      newlst.append(rest+(i,)) 
    return newlst 

這將保留順序,但在新列表上運行(不適用)。 如果需要,我會寫一個。

0

所以我覺得我有更多的Python的解決這個問題,我的代碼是:

result_lst = [] 
for tup in data[1:]: 
    result_lst+=[tup[0:2] + tuple([product]) for product in tup[2].split(',')] 
print result 
OUT: 
[('2013/03/07', 'Electronic', 'TV'), 
('2013/03/07', 'Electronic', ' Radio'), 
('2013/03/07', 'Electronic', ' Microwave'), 
('2013/03/07', 'leather', 'Gucci Wallet')] 
0
result = data[:1] 
for item in data[1:]: 
    (date, category, products) = item 
    result.extend(map(lambda product: (date, category, product), tuple(products.split(', ')))) 

print result 

這是因爲我可以作爲Python化...

輸出:

[('Date', 'Type', 'Product'), 
('2013/03/07', 'Electronic', 'TV'), 
('2013/03/07', 'Electronic', 'Radio'), 
('2013/03/07', 'Electronic', 'Microwave'), 
('2013/03/07', 'leather', 'Gucci Wallet')]