【问题标题】:Sublist to number子列表到编号
【发布时间】:2016-12-27 00:47:05
【问题描述】:

我正在努力解决我发现的一个有趣问题。我的代码给出了一堆子列表,比如 (1, 2, 3, 0, 0)。有没有办法将该子列表转换为数字 12300 并将其附加到新列表perm2?我必须对相当多的子列表执行此操作,所以最好它是我可以在整个列表上运行的函数(即,它会遍历列表,对每个数字进行转换,并将每个新数字附加到新列表,但旧列表将保持不变)。

到目前为止,我有代码

import itertools
digits = [1,2,3,0,0]
perm = list(itertools.permutations(digits))
perm2 = []

print perm
def lst_var (lst):
    for i in lst:
        litem = lst[i]
        #conversion takes place
        perm2.append(v)

lst_var(perm)

但我真的不知道如何进行转换,而且我在任何地方都找不到解决方案。任何帮助将不胜感激。

谢谢!

【问题讨论】:

  • 提示:12300 = 1 * 10000 + 2 * 1000 + 3 * 100 + 0 * 10 + 0

标签: python list function


【解决方案1】:

这是一个从数字列表中创建整数的函数。这个函数的优点是它不会将整数列表转换为字符串列表,这是一个相当昂贵的操作:

def list_to_int(ls):
    num = 0
    for digit in ls:
        num *= 10
        num += digit
    return num

应用于您的示例:

list_to_int([1,2,3,0,0])

12300

要将其应用于子列表列表,您可以使用列表推导式,或者我个人更喜欢map

sublists = [[7, 6, 6], [5, 7, 6], [9, 0, 9, 0], [8, 9, 5, 7, 8, 4]]
map(list_to_int, sublists)

[766、576、9090、895784]

因此,按照该模型,您的代码最终会看起来像:

digits = [1,2,3,0,0]
perm = map(list_to_int, itertools.permutations(digits))

【讨论】:

  • 感谢您的解决方案!
  • 如果你在num += digit之前做num *= 10,你可以避免除以10
  • 谢谢你,@AndreaCorbellini。刚刚在我的回答中采纳了你的建议。
【解决方案2】:

这里有几种不同的方法来解决这个问题:

1. perm2 = [int(''.join(str(i) for i in sublist)) for sublist in perm]

2. perm2 = [int(''.join(map(str, sublist))) for sublist in perm]

一个更性能的数学版本:

3. print [reduce(lambda x, y: 10 * x + y, sublist) for sublist in perm]

4. print map(lambda x: reduce(lambda x, y: 10 * x + y, x), perm)

此方法将列表转换为这种形式的字符串 -> 例如:[1, 2, 3, 4, 5] 首先使用 repr() 然后切片以返回子列表。

5. print [int(repr(sublist)[1::3]) for sublist in perm]

样本输出:

>>> import itertools
>>> digits = [1,2,3,0,0]
>>> perm = list(itertools.permutations(digits))
>>> perm2 = [int(''.join(map(str, sublist))) for sublist in perm]
>>> print perm2
[12300, 12300, 12030, 12003, 12030, 12003, 13200, 13200, 13020, 13002, 13020, 13002, 10230, 10203, 10320, 10302, 10023, 10032, 10230, 10203, 10320, 10302, 10023, 10032, 21300, 21300, 21030, 21003, 21030, 21003, 23100, 23100, 23010, 23001, 23010, 23001, 20130, 20103, 20310, 20301, 20013, 20031, 20130, 20103, 20310, 20301, 20013, 20031, 31200, 31200, 31020, 31002, 31020, 31002, 32100, 32100, 32010, 32001, 32010, 32001, 30120, 30102, 30210, 30201, 30012, 30021, 30120, 30102, 30210, 30201, 30012, 30021, 1230, 1203, 1320, 1302, 1023, 1032, 2130, 2103, 2310, 2301, 2013, 2031, 3120, 3102, 3210, 3201, 3012, 3021, 123, 132, 213, 231, 312, 321, 1230, 1203, 1320, 1302, 1023, 1032, 2130, 2103, 2310, 2301, 2013, 2031, 3120, 3102, 3210, 3201, 3012, 3021, 123, 132, 213, 231, 312, 321]

一些基准测试:

from timeit import timeit
repeat = 1000000
print 'Solution 1 took ->', timeit("import itertools;[int(''.join(str(i) for i in sublist)) for sublist in list(itertools.permutations([1,2,3,0,0]))]", number=repeat), 'secs'
print 'Solution 2 took ->', timeit("import itertools;[int(''.join(map(str, sublist))) for sublist in list(itertools.permutations([1,2,3,0,0]))]", number=repeat), 'secs'
print 'Solution 3 took ->', timeit("import itertools;map(lambda x: reduce(lambda x, y: 10 * x + y, x), list(itertools.permutations([1,2,3,0,0])))", number=repeat), 'secs'
print 'Solution 4 took ->', timeit("import itertools;[reduce(lambda x, y: 10 * x + y, sublist) for sublist in list(itertools.permutations([1,2,3,0,0]))]", number=repeat), 'secs'
print 'Solution 5 took ->', timeit("import itertools;[int(repr(sublist)[1::3]) for sublist in list(itertools.permutations([1,2,3,0,0]))]", number=repeat), 'secs'

结果(重复 = 1000000):

Solution 1 took -> 242.802856922 secs
Solution 2 took -> 153.20646596 secs
Solution 3 took -> 97.4842221737 secs
Solution 4 took -> 87.8391051292 secs
Solution 5 took -> 122.897110224 secs

【讨论】:

  • 谢谢你,这很好用,而且使用的代码更少!我会接受的。
  • 还添加了更短的理解。
  • @heather 请注意,如果考虑性能,这比数学方法慢几个数量级。 (基于在 python3 中通过 timeit 的快速运行。)
  • @glibdud,谢谢,我会考虑的。在这一点上,性能不是一个考虑因素,但它最终可能会成为一个考虑因素。
  • 我将使用较少的pythonic,高性能数学方式添加到我的答案中。
【解决方案3】:
digits = [1,2,3,0,0]
int(''.join([str(x) for x in digits]))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 2014-04-01
    • 2014-01-16
    • 1970-01-01
    • 2010-10-19
    • 2022-07-11
    • 1970-01-01
    • 2015-02-11
    相关资源
    最近更新 更多