是否有一种"简单"的方法将包含数字的str转换为[x,y]整数列表?
# from: '5,4,2,4,1,0,3,0,5,1,3,3,14,32,3,5'
# to: [[5, 4], [2, 4], [1, 0], [3, 0], [5, 1], [3, 3], [14, 32], [3, 5]]
Run Code Online (Sandbox Code Playgroud)
顺便说一句,下面的工作,但不会直接称之为...此外,可以假设输入str已经过验证,以确保它只包含偶数个逗号交错的数字.
num_str = '5,4,2,4,1,0,3,0,5,1,3,3,14,32,3,5'
numpairs_lst = [] # ends up as [[5, 4], [2, 4], [1, 0], ...]
current_num_str = '' # the current num within the str; stop when a comma is found
xy_pair = [] # this is one of the [x,y] pairs -> [5, 4]
for ix,c in enumerate(num_str):
if c == ',':
xy_pair.append(int(current_num_str))
current_num_str = ''
if len(xy_pair) == 2:
numpairs_lst.append(xy_pair)
xy_pair = []
else:
current_num_str += c
# and, take care of last number...
xy_pair.append(int(current_num_str))
numpairs_lst.append(xy_pair)
Run Code Online (Sandbox Code Playgroud)
daw*_*awg 22
Python中有两个重要的一行成语,有助于使这个"直截了当".
第一个成语,使用zip().从Python文档:
保证了迭代的从左到右的评估顺序.这使得使用zip(*[iter(s)]*n)将数据序列聚类成n长度组的习惯成为可能.
所以适用于你的例子:
>>> num_str = '5,4,2,4,1,0,3,0,5,1,3,3,14,32,3,5'
>>> zip(*[iter(num_str.split(","))]*2)
[('5', '4'), ('2', '4'), ('1', '0'), ('3', '0'), ('5', '1'),
('3', '3'), ('14', '32'), ('3', '5')]
Run Code Online (Sandbox Code Playgroud)
这会生成每个长度为2的元组.
如果您希望子元素的长度不同:
>>> zip(*[iter(num_str.split(","))]*4)
[('5', '4', '2', '4'), ('1', '0', '3', '0'), ('5', '1', '3', '3'),
('14', '32', '3', '5')]
Run Code Online (Sandbox Code Playgroud)
第二个习语是列表理解.如果您希望子元素成为列表,请理解:
>>> [list(t) for t in zip(*[iter(num_str.split(","))]*4)]
[['5', '4', '2', '4'], ['1', '0', '3', '0'], ['5', '1', '3', '3'],
['14', '32', '3', '5']]
>>> [list(t) for t in zip(*[iter(num_str.split(","))]*2)]
[['5', '4'], ['2', '4'], ['1', '0'], ['3', '0'], ['5', '1'], ['3', '3'],
['14', '32'], ['3', '5']]
Run Code Online (Sandbox Code Playgroud)
任何不完整的子元素组都将被zip()截断.因此,如果您的字符串不是2的倍数,那么您将丢失最后一个元素.
如果要返回不完整的子元素(即,如果您num_str
不是子元素长度的倍数),请使用切片习语:
>>> l=num_str.split(',')
>>> [l[i:i+2] for i in range(0,len(l),2)]
[['5', '4'], ['2', '4'], ['1', '0'], ['3', '0'], ['5', '1'],
['3', '3'], ['14', '32'], ['3', '5']]
>>> [l[i:i+7] for i in range(0,len(l),7)]
[['5', '4', '2', '4', '1', '0', '3'], ['0', '5', '1', '3', '3', '14', '32'],
['3', '5']]
Run Code Online (Sandbox Code Playgroud)
如果您希望每个元素都是一个int,您可以在此处讨论的其他变换之前应用它:
>>> nums=[int(x) for x in num_str.split(",")]
>>> zip(*[iter(nums)]*2)
# etc etc etc
Run Code Online (Sandbox Code Playgroud)
正如在评论中指出,与Python 2.4及以上的,也可以替换为列表解析生成器表达式通过更换[ ]
具有( )
如下所示:
>>> nums=(int(x) for x in num_str.split(","))
>>> zip(nums,nums)
[(5, 4), (2, 4), (1, 0), (3, 0), (5, 1), (3, 3), (14, 32), (3, 5)]
# or map(list,zip(nums,nums)) for the list of lists version...
Run Code Online (Sandbox Code Playgroud)
如果你的字符串很长,并且你知道你只需要2个元素,那么效率会更高.
Fel*_*ing 15
一种选择:
>>> num_str = '5,4,2,4,1,0,3,0,5,1,3,3,4,3,3,5'
>>> l = num_str.split(',')
>>> zip(l[::2], l[1::2])
[('5', '4'), ('2', '4'), ('1', '0'), ('3', '0'), ('5', '1'), ('3', '3'), ('4', '3'), ('3', '5')]
Run Code Online (Sandbox Code Playgroud)
参考:str.split()
,zip()
,关于序列类型和切片的一般信息
如果你真的想要整数,你可以先使用map
以下命令将列表转换为整数:
>>> l = map(int, num_str.split(','))
Run Code Online (Sandbox Code Playgroud)
说明:
split
创建单个元素的列表.诀窍是切片:语法是list[start:end:step]
.l[::2]
将返回从第一个元素开始的每个第二个元素(所以第一个,第三个,......),而第二l[1::2]
个元素从第二个元素返回每个第二个元素(所以第二个,第四个,......).
更新:如果您确实需要列表,可以map
在结果列表中再次使用:
>>> xy_list = map(list, xy_list)
Run Code Online (Sandbox Code Playgroud)
请注意,@ Johnsyweb的答案可能更快,因为它似乎没有做任何不必要的迭代.但实际差异当然取决于列表的大小.
Joh*_*web 11
#!/usr/bin/env python
from itertools import izip
def pairwise(iterable):
"s -> (s0,s1), (s2,s3), (s4, s5), ..."
a = iter(iterable)
return izip(a, a)
s = '5,4,2,4,1,0,3,0,5,1,3,3,4,3,3,5'
fields = s.split(',')
print [[int(x), int(y)] for x,y in pairwise(fields)]
Run Code Online (Sandbox Code Playgroud)
取自@ martineau对我的问题的回答,我发现这个问题非常快.
输出:
[[5, 4], [2, 4], [1, 0], [3, 0], [5, 1], [3, 3], [4, 3], [3, 5]]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2756 次 |
最近记录: |