2016-10-31 60 views
3

我想從多字段字符串列表中創建一個列表列表,並想知道在理解中是否可以這樣做。列表理解中的多個變量?

輸入:

inputs = ["1, foo, bar", "2, tom, jerry"] 

所需的輸出:

[[1, "foo", "bar"], [2, "tom", "jerry"]] 

分割的理解字符串很簡單:

>>> [s.split(",") for s in inputs] 
[['1', ' foo', ' bar'], ['2', ' tom', ' jerry']] 

,但我有麻煩找出如何訪問字符串之後的列已經被分解到理解中,因爲它似乎需要變量可分配。以下是無效的Python,但說明我正在尋找:

[[int(x), y.strip(), z.strip() for x,y,z = s.split(",")] for s in inputs] 
    or 
[[int(v[0]), v[1].strip(), v[2].strip() for v = s.split(",")] for s in inputs] 

是否有指定的理解裏面的變量,使輸出可組成的變量的函數的方法嗎?一個循環是微不足道的,但通過轉換輸入確定一個列表看起來像是一個「理解 - 伊什」任務。

outputs = [] 
for s in inputs: 
    x,y,z = s.split(",") 
    outputs.append([int(x), y.strip(), z.strip()]) 
+0

你可以訪問他們的索引的元素。對於'[['1','foo','bar'],['2','tom','jerry']]','lst [0] [0]'是'1','lst [0] [1]'是'foo'等等。如果你需要變量,你可能需要將它們存儲爲帶有鍵的映射。 – shaktimaan

+4

'[... for x,y,z in(s.split(',')for s in inputs)]' – jonrsharpe

回答

3

您可以在您的列表理解2項for條款做到這一點。第一個遍歷列表中的項目。第二個遍歷包含從分割字符串派生的列表的單個項目列表(這是需要的,因此我們可以將其解壓縮爲三個單獨的變量)。

[[int(x), y.strip(), z.strip()] for s in inputs for (x, y, z) in [s.split(",")]] 

for條款進去有點違反直覺的順序,但你會寫嵌套循環for的方式相匹配。

Jon Sharpe使用嵌套理解(實際上是生成器表達式)是相似的,可能更清晰。使用多個for子句總是讓我感到困惑;主要是我想看看我能否在這裏使用它。

1

如果你真的想這樣做在同一行,你可以做這樣的事情,雖然它不是最清晰的代碼(第一行代碼,第二行是輸出)。

>>> [(lambda x, y, z: [int(x), y.strip(), z.strip()])(*s.split(",")) for s in inputs] 
[[1, 'foo', 'bar'], [2, 'tom', 'jerry']] 

或這個。

>>> [(lambda x: [int(x[0]), x[1].strip(), x[2].strip()])(s.split(",")) for s in inputs] 
[[1, 'foo', 'bar'], [2, 'tom', 'jerry'] 

編輯:爲最佳答案恕我直言 見jonrsharpe的評論。

+0

我正在考慮lambda,但希望儘可能避免它 - 謝謝你的工作示例。 – Dave

1

您可以使用地圖列表理解

def clean(x): 
    return [int(x[0]), x[1].strip(), x[2].strip()] 

map(clean,[s.split(",") for s in inputs]) 
# Output: [[1, 'foo', 'bar'], [2, 'tom', 'jerry']] 

與lambda函數:

map(lambda x: [int(x[0]), x[1].strip(), x[2].strip()],[s.split(",") for s in inputs]) 
0

另一種可能的解決方案

>>> inputs = [[1, "foo", "bar"], [2, "tom", "jerry"]] 
>>> list_of_dicts = [{"var{}".format(k): v for k, v in enumerate(s, start=1)} for s in inputs] 
>>> list_of_dicts[0]['var1'] 
1 
>>> list_of_dicts[0]['var2'] 
'foo' 
1

感謝所有的建議 - 我們很高興地看到各種可能的技術,以及一個反Python的禪宗「應該有一個 - 並且最好只有一個 - 明顯的方式來做到這一點。「

所有4種解決方案都同樣美麗,所以有必要只向其中一個人提供令人垂涎的綠色支票是有點不公平的,我同意#1是最乾淨和最好的方法。直截了當的理解,但不得不在理解中使用lambda似乎有點關鍵###################################作爲地圖創建迭代器的好材料,但需要額外的迭代過程纔會有一點小缺點。嵌套的是可能的 - 如果我能記得他們以「第一,第二」順序而不是「內部,外部」順序排列。由於#1不是答案的形式,所以#4會得到最令人驚訝的檢查。

再次感謝所有人

inputs = ["1, foo, bar", "2,tom, jerry"] 

outputs1 = [[int(x), y.strip(), z.strip()] for x,y,z in (s.split(',') for s in inputs)] 
print("1:", outputs1)  # jonrsharpe 

outputs2 = [(lambda x, y, z: [int(x), y.strip(), z.strip()])(*s.split(",")) for s in inputs] 
print("2:", outputs2)  # yper 

outputs3 = [z for z in map(lambda x: [int(x[0]), x[1].strip(), x[2].strip()],[s.split(",") for s in inputs])] 
print("3:", outputs3)  # user2314737 

outputs4 = [[int(x), y.strip(), z.strip()] for s in inputs for (x, y, z) in [s.split(",")]] 
print("4:", outputs4)  # kindall 

結果:

1: [[1, 'foo', 'bar'], [2, 'tom', 'jerry']] 
2: [[1, 'foo', 'bar'], [2, 'tom', 'jerry']] 
3: [[1, 'foo', 'bar'], [2, 'tom', 'jerry']] 
4: [[1, 'foo', 'bar'], [2, 'tom', 'jerry']]