2014-01-18 68 views
4

我想從Excel複製一些表格數據到python數組。也就是說,用戶將在Excel表格中選擇一個範圍,按「複製」(CTRL + C),以便將範圍複製到剪貼板。然後我將這個剪貼板數據放入一個python數組(列表)中。我用win32clipboardfrom pywin32得到剪貼板數據到一個數組:如何在python中換行時分割字符串?

import win32clipboard 

def getClip(): 
    win32clipboard.OpenClipboard() 
    data = win32clipboard.GetClipboardData() 
    win32clipboard.CloseClipboard() 
    return data 

我從Excel複製以下範圍A1:B5

enter image description here

當我使用上面的功能,得到了一個串,如:

'365\t179\r\n96\t-90\r\n48\t-138\r\n12\t-174\r\n30\t-156\r\n' 

如何將此字符串拆分爲一個列表,以便列表如下所示:

[(365,179), (96, -90), (48, -138), (12, -174), (30, -156)] 

我使用split方法,但它並沒有給我我想要的。

data.split("\n") 

['365\t179\r', '96\t-90\r', '48\t-138\r', '12\t-174\r', '30\t-156\r', ''] 

回答

6
>>> s = '365\t179\r\n96\t-90\r\n48\t-138\r\n12\t-174\r\n30\t-156\r\n' 
>>> [map(int, x.split('\t')) for x in s.rstrip().split('\r\n')] 
[[365, 179], [96, -90], [48, -138], [12, -174], [30, -156]] 

從我other answer使用代碼,您還可以處理其他類型還有:

from ast import literal_eval 
def solve(x): 
    try: 
     return literal_eval(x) 
    except (ValueError, SyntaxError): 
     return x 

s = '365\tFoo\r\nBar\t-90.01\r\n48\tspam\r\n12e10\t-174\r\n30\t-156\r\n' 
print [map(solve, x.split('\t')) for x in s.rstrip().split('\r\n')] 
#[[365, 'Foo'], ['Bar', -90.01], [48, 'spam'], [120000000000.0, -174], [30, -156]] 
+0

如果複製Excel範圍有5行10列?然後,列表應該有5個內部列表,並且每個內部列表應該有10個項目。你的解決方案會提供這個嗎 – alwbtc

+1

@alwbtc是的。它會:) – thefourtheye

+0

好的,但如果範圍一起包含字符串和整數呢? – alwbtc

1
In [85]: zip(*[iter(map(int, data.split()))]*2) 
Out[85]: [(365, 179), (96, -90), (48, -138), (12, -174), (30, -156)] 

這裏是它如何工作的一個細分:

首先,在空格上分割:

In [86]: data.split() 
Out[86]: ['365', '179', '96', '-90', '48', '-138', '12', '-174', '30', '-156'] 

轉換字符串到整數:

In [87]: map(int, data.split()) 
Out[87]: [365, 179, 96, -90, 48, -138, 12, -174, 30, -156] 

使用grouper recipe到組每2項:

In [88]: zip(*[iter(map(int, data.split()))]*2) 
Out[88]: [(365, 179), (96, -90), (48, -138), (12, -174), (30, -156)] 
+0

如果複製的Excel範圍有5行10列,那該怎麼辦?然後列表應該有5個元組,每個元組應該有10個項目。解決方案提供了這個? – alwbtc

+0

@alwbtc:它可以,但你必須在石斑魚配方中將2更改爲10如果你不知道每個元組中應該有多少項目, t'會是b埃特。 – unutbu

0
[line.split() for line in my_str.split("\n")] 

這只是將數據劃分成線,然後將其分解根據白色空間。根據你的數據檢查出來並修改。

2
d = '365\t179\r\n96\t-90\r\n48\t-138\r\n12\t-174\r\n30\t-156\r\n' 
print [tuple(map(int,item.split(","))) for item in d.replace("\t", ",").split()] 

輸出

[(365, 179), (96, -90), (48, -138), (12, -174), (30, -156)] 
5

實際上,有一個str.splitlines方法將由換行符,分割字符串無論其用於換行的。所以這適用於只有\n的Unix系統,在Windows上使用\r\n,甚至在舊的Mac系統中,換行符只是一個\r

>>> s = '365\t179\r\n96\t-90\r\n48\t-138\r\n12\t-174\r\n30\t-156\r\n' 
>>> s.splitlines() 
['365\t179', '96\t-90', '48\t-138', '12\t-174', '30\t-156'] 

一旦你有了這個結果,你可以通過製表符分割來獲得單個單元格。所以你必須在每個單元上調用cell.split('\t')。這最好用一個列表理解來完成:

>>> [row.split('\t') for row in s.splitlines()] 
[['365', '179'], ['96', '-90'], ['48', '-138'], ['12', '-174'], ['30', '-156']] 

作爲替代方案,你也可以使用map適用於每一個細胞的分離操作:

>>> list(map(lambda cell: cell.split('\t'), s.splitlines())) 
[['365', '179'], ['96', '-90'], ['48', '-138'], ['12', '-174'], ['30', '-156']] 

由於在剪貼板複製的數據將始終用換行符分隔的行和由製表符分隔的列,此解決方案也可以安全地用於您複製的任何單元格範圍。

如果您還想要轉換的整數或浮點數在Python其正確的數據類型,我想你可以通過調用int()上只有數字在他們的所有單元格,float()在具有數字和所有單元格添加一些更多的轉換邏輯點在他們.,留下其餘爲字符串:

>>> def convert (cell): 
     try: 
      return int(cell) 
     except ValueError: 
      try: 
       return float(cell) 
      except ValueError: 
       return cell 
>>> [tuple(map(convert, row.split('\t'))) for row in s.splitlines()] 
[(365, 179), (96, -90), (48, -138), (12, -174), (30, -156)] 

對於不同的字符串:

>>> s = 'Foo\tbar\r\n123.45\t42\r\n-85\t3.14' 
>>> [tuple(map(convert, row.split('\t'))) for row in s.splitlines()] 
[('Foo', 'bar'), (123.45, 42), (-85, 3.14)]