python:转换“5,4,2,4,1,0"进入 [[5, 4], [2, 4], [1, 0]] [英] python: convert "5,4,2,4,1,0" into [[5, 4], [2, 4], [1, 0]]

查看:48
本文介绍了python:转换“5,4,2,4,1,0"进入 [[5, 4], [2, 4], [1, 0]]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种直接"的方法来转换包含将数字转换为 [x,y] 整数列表?

# from: '5,4,2,4,1,0,3,0,5,1,3,3,14,32,3,5'# 到: [[5, 4], [2, 4], [1, 0], [3, 0], [5, 1], [3, 3], [14, 32], [3, 5]]

顺便说一句,下面的工作,但不会称之为直截了当......此外,可以假设输入 str 已经过验证以确保它只包含偶数个由逗号交错的数字.

num_str = '5,4,2,4,1,0,3,0,5,1,3,3,14,32,3,5'numpairs_lst = [] # 最终为 [[5, 4], [2, 4], [1, 0], ...]current_num_str = '' # str 中的当前 num;找到逗号时停止xy_pair = [] # 这是 [x,y] 对之一 ->[5, 4]对于枚举(num_str)中的 ix,c:如果 c == ',':xy_pair.append(int(current_num_str))current_num_str = ''如果 len(xy_pair) == 2:numpairs_lst.append(xy_pair)xy_pair = []别的:current_num_str += c# 并且,注意最后一个数字...xy_pair.append(int(current_num_str))numpairs_lst.append(xy_pair)

解决方案

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')]

这会产生长度为 2 的元组.

如果你想让子元素的长度不同:

<预><代码>>>>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(","))]*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']]

任何不完整的子元素组都将被 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']]

如果您希望每个元素都是 int,您可以在此处讨论的其他转换之前应用它:

<预><代码>>>>nums=[int(x) for x in num_str.split(",")]>>>zip(*[iter(nums)]*2)# 等等等等

正如评论中所指出的,使用 Python 2.4+,您还可以用 Generator 替换列表理解将 [ ] 替换为 ( ) 的表达式,如下所示:

<代码> >>>nums=(int(x) for x in num_str.split(","))>>>邮编(编号,编号)[(5, 4), (2, 4), (1, 0), (3, 0), (5, 1), (3, 3), (14, 32), (3, 5)]# 或 map(list,zip(nums,nums)) 用于列表版本...

如果你的字符串很长,而且你知道你只需要 2 个元素,这会更有效率.

Is there a "straightforward" way to convert a str containing numbers into a list of [x,y] ints?

# 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]]

By the way, the following works, but wouldn't call it straightforward... Also, it can be assumed that the input str has been validated to make sure that it only contains an even number of numbers interleaved by commas.

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)

解决方案

There are two important one line idioms in Python that help make this "straightforward".

The first idiom, use zip(). From the Python documents:

The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups using zip(*[iter(s)]*n).

So applying to your example:

>>> 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')]

That produces tuples each of length 2.

If you want the length of the sub elements to be different:

>>> zip(*[iter(num_str.split(","))]*4)
[('5', '4', '2', '4'), ('1', '0', '3', '0'), ('5', '1', '3', '3'), 
('14', '32', '3', '5')]

The second idiom is list comprehensions. If you want sub elements to be lists, wrap in a comprehension:

>>> [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']]

Any sub element groups that are not complete will be truncated by zip(). So if your string is not a multiple of 2, for example, you will loose the last element.

If you want to return sub elements that are not complete (ie, if your num_str is not a multiple of the sub element's length) use a slice idiom:

>>> 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']]

If you want each element to be an int, you can apply that prior to the other transforms discussed here:

>>> nums=[int(x) for x in num_str.split(",")]
>>> zip(*[iter(nums)]*2)
# etc etc etc

As pointed out in the comments, with Python 2.4+, you can also replace the list comprehension with a Generator Expression by replacing the [ ] with ( ) as in:

 >>> 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...

If your string is long, and you know that you only need 2 elements, this is more efficient.

这篇关于python:转换“5,4,2,4,1,0"进入 [[5, 4], [2, 4], [1, 0]]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆