簡體   English   中英

在Python中分割字串時,值解包的怪異行為

[英]Weird behavior of Value unpacking when splitting string in Python

用例:我有一個很長的字符串,該字符串被換行符分隔,並且每行都有兩個用逗號分隔的元素。

理想情況下,這應該可行

[(x, y) for line in lines.split() for x, y in line.split(',')]

但事實並非如此,並產生與下面相同的ValueError。 所以我試圖分解問題以弄清楚這里發生了什么

lines = \
"""a,b
c,d
e,f
g,h"""

lines = [line for line in lines.split()]

print(lines)
print(len(lines))
print([len(line) for line in lines])
print(all(',' in line for line in lines))

[(x, y) for l in lines for x,y in l.split(',')]

產量:

/usr/bin/python3m /home/alex/PycharmProjects/test.py
['a,b', 'c,d', 'e,f', 'g,h']
4
[3, 3, 3, 3]
True

Traceback (most recent call last):
File "/home/alex/PycharmProjects/test.py", line 74, in <module>
...
File "/home/alex/PycharmProjects/test.py", line 63, in <listcomp>
[(x, y) for l in sines for x,y in l.split(',')]
ValueError: need more than 1 value to unpack

但是,如果我用經典的for循環替換最后一行中的列表理解:

for line in lines:
x, y = line.split(',')

它成功執行:

['a,b', 'c,d', 'e,f', 'g,h']
4
True
[3, 3, 3, 3]
a b
c d
e f
g h

這真讓我發瘋。 如果我進一步分解它,我會發現列表,集合和生成器理解本身會嘗試這樣做:

[(x,y) for x, y in "a,b".split(",")]

任何人都知道為什么會這樣嗎?

這段代碼:

for x, y in "a,b".split(",")

正在尋找"a,b".split(",")返回的可迭代(列表) 內部兩個項目可迭代。

但是,它找到的只是'a''b'

>>> "a,b".split(",")
['a', 'b']
>>>

由於這兩個都是單項可迭代 (帶有一個字符的字符串),因此代碼會中斷。


考慮到上述情況,請注意將多余的字符添加到逗號的兩側時會發生什么:

>>> "ax,by".split(",")
['ax', 'by']
>>> [(x,y) for x, y in "ax,by".split(",")]
[('a', 'x'), ('b', 'y')]
>>>

如您所見,該代碼現在可以工作了。

這是因為"ax,by".split(",")返回一個包含兩個項目可迭代項(帶有兩個字符的字符串"ax,by".split(",")的可迭代項(列表)。 此外,這正是for x, y in要查找的。


但是,您也可以將最后一部分放在元組中:

>>> ("a,b".split(","),)
(['a', 'b'],)
>>> [(x,y) for x, y in ("a,b".split(","),)]
[('a', 'b')]
>>>

("a,b".split(","),)返回包含兩個項目可迭代項(包含兩個字符串的列表("a,b".split(","),)的可迭代(元組)。 再一次,這正是for x, y in要查找的內容,因此代碼可以正常工作。


考慮到所有這些,以下內容將解決您的問題:

[(x, y) for line in lines.split() for x, y in (line.split(','),)]

為什么不呢?

[tuple(l.split(',')) for l in lines ]

l.split(',')只產生兩個項目對於每個l ,而不是為每次兩個項目迭代l

為什么不只是:

lines = """
a,b
c,d
e,f
g,h
"""

lines = [line for line in lines.split()]

print(lines)
print(len(lines))
print([len(line) for line in lines])
print(all(',' in line for line in lines))

[l.split(",") for l in lines]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM