如何将列表整数和字符串合并为一个字符串?
How to concat lists integers and strings into one string?
我有以下变量:
a = [1, 2, 3]
b = "de" # <-- not a (usual) list !
c = 5 # <-- not a list !
d = [4, 5, 23, 11, 5]
e = ["dg", "kuku"]
现在我想将所有 a, b, c, d, e
连接到一个列表中:
[1, 2, 3, "de", 5, 4, 5, 23, 11, 5, "dg", "kuku"]
我试过 itertools.chain
但没用。请告知如何进行串联?
您必须合并 append()
和 extend()
,因为您的示例之一不是 list
(b
和 c
),而是一个整数.
#!/usr/bin/env python3
a = [1, 2, 3]
b = "de"
c = 5
d = [4, 5, 23, 11, 5]
e = ["dg", "kuku"]
the_input = [a, b, c, d, e]
result = []
for element in the_input:
if isinstance(element, list):
result.extend(element)
else:
result.append(element)
print(result)
我不知道有任何类似链的方法可以改进该示例。
chain
适用于可迭代对象。你的意思是:连接这些列表和原始值。
我看到两个步骤:
def ensure_list(x):
if isinstance(x, list):
return x
return [x]
lists = map(ensure_list, (a, b, c, d, e))
concatenated = list(itertools.chain.from_iterable(lists))
您可以定义一个函数,它接受任意数量的参数并根据它们的类型迭代地构建一个列表,如下所示:
a = [1, 2, 3]
b = "de" # <-- not a (usual) list !
c = 5 # <-- not a list !
d = [4, 5, 23, 11, 5]
e = ["dg", "kuku"]
def concat(*args):
out = []
for arg in args:
if isinstance(arg, list):
out.extend(arg)
else:
out.append(arg)
return out
print(concat(a,b,c,d,e))
输出:
[1, 2, 3, 'de', 5, 4, 5, 23, 11, 5, 'dg', 'kuku']
或者,您可以映射 args 列表,确保它们都是列表,然后使用 itertools.chain
组合映射对象,如下所示:
def concat(*args):
return list(itertools.chain(*map(lambda x : x if isinstance(x, list) else [x], args)))
print(concat(a,b,c,d,e))
输出:
[1, 2, 3, 'de', 5, 4, 5, 23, 11, 5, 'dg', 'kuku']
这里有一种更不透明的方式来完成同样的事情,只是为了在列表理解中获得乐趣:
def concat(*args):
return [x
for arg in args
for x in (arg if isinstance(arg, list) else [arg])]
print(concat(a,b,c,d,e))
输出:
[1, 2, 3, 'de', 5, 4, 5, 23, 11, 5, 'dg', 'kuku']
您还可以创建一个带有 map 的生成器,它生成参数或列表中的参数,然后将它们与列表相加(您可能实际上不应该这样做,但它很简洁)。
def concat(*args):
return sum(map(lambda arg : arg if isinstance(arg,list) else [arg], args), [])
print(concat(a,b,c,d,e))
输出:
[1, 2, 3, 'de', 5, 4, 5, 23, 11, 5, 'dg', 'kuku']
我不推荐这样做,但如果您喜欢列表理解或 one-liners:
,这里有另一种方法
to_concat = [a, b, c]
concatenated_list = []
concatenated_list += [item for sublist in [[list_or_val] if not isinstance(list_or_val, list) else list_or_val for list_or_val in to_concat] for item in sublist]
输出 a, b, c = "de", [1, 2], ["dg", "kuku"]
:
In [6]: concatenated_list
Out[6]: ['de', 1, 2, 'dg', 'kuku']
它是如何工作的?
这部分:
[[list_or_val] if not isinstance(list_or_val, list) else list_or_val for list_or_val in to_concat]
的列表推导式通过将 non-list 值(如本例中的 a
)转换为列表(因此 "de"
变为 ["de"]
)来创建一个新列表。我们称它为 list_of_lists
。我们现在想要展平 list_of_lists
以获得我们的最终结果,我们可以通过列表推导的另一部分来实现:
[item for sublist in list_of_lists for item in sublist]
(有关扁平化的更多信息 here,如果您有兴趣)
如我所说,我不推荐此解决方案。理解起来相当混乱,而且它的性能可能很糟糕,因此它不适合更大的工作负载。
好问题 - 它导致制作一些我将放入我的实用程序工具箱的东西:
自定义生成器 - chainanything()
我会创建辅助函数作为生成器而不是返回列表。这使它的使用更加灵活,并且通常速度更快一点。如果我有一个 returns 列表的函数,我通常会这样做。
def chainanything(*args, preservestrings=True, recursive=False):
"""
Generator: yields the contents of a Sequence, or the given object if not a Sequence, one at a time
preservestrings = False will lead to strings being yielded as individual characters. Default = True
recursive = True will recursively flatten sequences. Default = False
Note: preservestrings = False, recursive = False will only flatten strings which are not part of another Sequence.
e.g.: 'abc' -> 'a','b','c' but ['ab','cd'] -> 'ab','cd'
"""
args = [*args]
for arg in args:
if not isinstance(arg, Sequence):
yield arg
else:
if preservestrings and isinstance(arg, str):
yield arg
elif recursive:
yield from flatten(arg)
else:
yield from arg
然后可以以标准形式使用它来提供您的预期结果:
def test_preservestring():
# https://whosebug.com/questions/72288401/how-to-concat-lists-integers-and-strings-into-one-string/72288721#72288721
a = [1, 2, 3]
b = "de" # <-- not a (usual) list !
c = 5 # <-- not a list !
d = [4, 5, 23, 11, 5]
e = ["dg", "kuku"]
assert [x for x in chainanything(a,b,c,d,e)] == [1, 2, 3, "de", 5, 4, 5, 23, 11, 5, "dg", "kuku"]
或用join
和map
回答标题中的问题并将它们连接成一个字符串:
def test_join():
a = [1, 2, 3]
b = "de" # <-- not a (usual) list !
c = 5 # <-- not a list !
d = [4, 5, 23, 11, 5]
e = ["dg", "kuku"]
assert ''.join(map(str,chainanything(a,b,c,d,e))) == "123de54523115dgkuku"
为了以合乎逻辑的方式处理字符串,整个函数比一行稍长。
展平函数递归展平序列 - 这是我为我的工具箱创建的另一个小助手生成器:
def flatten(seq):
"""
Recursively flattens a sequence (including strings!) and returns all elements in order left to right.
E.g.: [1,2,[3,4,[5],6],7,[8,9]] -> [1,2,3,4,5,6,7,8,9]
"""
for item in seq:
if not isinstance(item, Sequence):
yield item
elif len(item) == 1 and item[0] == item: #eg item = 'a'
yield item[0]
else:
yield from flatten(item)
您可以在此处获取最新版本的助手:https://dev.azure.com/MusicalNinjas/_git/MikesMath
我有以下变量:
a = [1, 2, 3]
b = "de" # <-- not a (usual) list !
c = 5 # <-- not a list !
d = [4, 5, 23, 11, 5]
e = ["dg", "kuku"]
现在我想将所有 a, b, c, d, e
连接到一个列表中:
[1, 2, 3, "de", 5, 4, 5, 23, 11, 5, "dg", "kuku"]
我试过 itertools.chain
但没用。请告知如何进行串联?
您必须合并 append()
和 extend()
,因为您的示例之一不是 list
(b
和 c
),而是一个整数.
#!/usr/bin/env python3
a = [1, 2, 3]
b = "de"
c = 5
d = [4, 5, 23, 11, 5]
e = ["dg", "kuku"]
the_input = [a, b, c, d, e]
result = []
for element in the_input:
if isinstance(element, list):
result.extend(element)
else:
result.append(element)
print(result)
我不知道有任何类似链的方法可以改进该示例。
chain
适用于可迭代对象。你的意思是:连接这些列表和原始值。
我看到两个步骤:
def ensure_list(x):
if isinstance(x, list):
return x
return [x]
lists = map(ensure_list, (a, b, c, d, e))
concatenated = list(itertools.chain.from_iterable(lists))
您可以定义一个函数,它接受任意数量的参数并根据它们的类型迭代地构建一个列表,如下所示:
a = [1, 2, 3]
b = "de" # <-- not a (usual) list !
c = 5 # <-- not a list !
d = [4, 5, 23, 11, 5]
e = ["dg", "kuku"]
def concat(*args):
out = []
for arg in args:
if isinstance(arg, list):
out.extend(arg)
else:
out.append(arg)
return out
print(concat(a,b,c,d,e))
输出:
[1, 2, 3, 'de', 5, 4, 5, 23, 11, 5, 'dg', 'kuku']
或者,您可以映射 args 列表,确保它们都是列表,然后使用 itertools.chain
组合映射对象,如下所示:
def concat(*args):
return list(itertools.chain(*map(lambda x : x if isinstance(x, list) else [x], args)))
print(concat(a,b,c,d,e))
输出:
[1, 2, 3, 'de', 5, 4, 5, 23, 11, 5, 'dg', 'kuku']
这里有一种更不透明的方式来完成同样的事情,只是为了在列表理解中获得乐趣:
def concat(*args):
return [x
for arg in args
for x in (arg if isinstance(arg, list) else [arg])]
print(concat(a,b,c,d,e))
输出:
[1, 2, 3, 'de', 5, 4, 5, 23, 11, 5, 'dg', 'kuku']
您还可以创建一个带有 map 的生成器,它生成参数或列表中的参数,然后将它们与列表相加(您可能实际上不应该这样做,但它很简洁)。
def concat(*args):
return sum(map(lambda arg : arg if isinstance(arg,list) else [arg], args), [])
print(concat(a,b,c,d,e))
输出:
[1, 2, 3, 'de', 5, 4, 5, 23, 11, 5, 'dg', 'kuku']
我不推荐这样做,但如果您喜欢列表理解或 one-liners:
,这里有另一种方法to_concat = [a, b, c]
concatenated_list = []
concatenated_list += [item for sublist in [[list_or_val] if not isinstance(list_or_val, list) else list_or_val for list_or_val in to_concat] for item in sublist]
输出 a, b, c = "de", [1, 2], ["dg", "kuku"]
:
In [6]: concatenated_list
Out[6]: ['de', 1, 2, 'dg', 'kuku']
它是如何工作的?
这部分:
[[list_or_val] if not isinstance(list_or_val, list) else list_or_val for list_or_val in to_concat]
的列表推导式通过将 non-list 值(如本例中的 a
)转换为列表(因此 "de"
变为 ["de"]
)来创建一个新列表。我们称它为 list_of_lists
。我们现在想要展平 list_of_lists
以获得我们的最终结果,我们可以通过列表推导的另一部分来实现:
[item for sublist in list_of_lists for item in sublist]
(有关扁平化的更多信息 here,如果您有兴趣)
如我所说,我不推荐此解决方案。理解起来相当混乱,而且它的性能可能很糟糕,因此它不适合更大的工作负载。
好问题 - 它导致制作一些我将放入我的实用程序工具箱的东西:
自定义生成器 - chainanything()
我会创建辅助函数作为生成器而不是返回列表。这使它的使用更加灵活,并且通常速度更快一点。如果我有一个 returns 列表的函数,我通常会这样做。
def chainanything(*args, preservestrings=True, recursive=False):
"""
Generator: yields the contents of a Sequence, or the given object if not a Sequence, one at a time
preservestrings = False will lead to strings being yielded as individual characters. Default = True
recursive = True will recursively flatten sequences. Default = False
Note: preservestrings = False, recursive = False will only flatten strings which are not part of another Sequence.
e.g.: 'abc' -> 'a','b','c' but ['ab','cd'] -> 'ab','cd'
"""
args = [*args]
for arg in args:
if not isinstance(arg, Sequence):
yield arg
else:
if preservestrings and isinstance(arg, str):
yield arg
elif recursive:
yield from flatten(arg)
else:
yield from arg
然后可以以标准形式使用它来提供您的预期结果:
def test_preservestring():
# https://whosebug.com/questions/72288401/how-to-concat-lists-integers-and-strings-into-one-string/72288721#72288721
a = [1, 2, 3]
b = "de" # <-- not a (usual) list !
c = 5 # <-- not a list !
d = [4, 5, 23, 11, 5]
e = ["dg", "kuku"]
assert [x for x in chainanything(a,b,c,d,e)] == [1, 2, 3, "de", 5, 4, 5, 23, 11, 5, "dg", "kuku"]
或用join
和map
回答标题中的问题并将它们连接成一个字符串:
def test_join():
a = [1, 2, 3]
b = "de" # <-- not a (usual) list !
c = 5 # <-- not a list !
d = [4, 5, 23, 11, 5]
e = ["dg", "kuku"]
assert ''.join(map(str,chainanything(a,b,c,d,e))) == "123de54523115dgkuku"
为了以合乎逻辑的方式处理字符串,整个函数比一行稍长。
展平函数递归展平序列 - 这是我为我的工具箱创建的另一个小助手生成器:
def flatten(seq):
"""
Recursively flattens a sequence (including strings!) and returns all elements in order left to right.
E.g.: [1,2,[3,4,[5],6],7,[8,9]] -> [1,2,3,4,5,6,7,8,9]
"""
for item in seq:
if not isinstance(item, Sequence):
yield item
elif len(item) == 1 and item[0] == item: #eg item = 'a'
yield item[0]
else:
yield from flatten(item)
您可以在此处获取最新版本的助手:https://dev.azure.com/MusicalNinjas/_git/MikesMath