我知道连接字符串列表的pythonic方法是使用
l =["a", "b", "c"]
"".join(l)
但是如果我有一个包含字符串(作为属性)的对象列表,而不重新分配字符串,我该如何做呢?
我想我可以实施__str__(self)
。但这是我不愿意使用的解决方法。
答案 0 :(得分:10)
我想最强的 pythonic 方法是使用生成器表达式/列表理解。
如果字符串例如是对象obj_instance.str_attr
的属性
然后运行:
"".join(x.str_attr for x in l)
或
"".join([x.str_attr for x in l])
<强>编辑强>: 请参阅(they claim that list comprehension - 2nd option is faster下面关于绩效的讨论。
答案 1 :(得分:4)
如下:
joined = "".join([object.string for object in lst_object])
答案 2 :(得分:4)
生成器表达式和列表理解之间的性能差异很容易衡量:
python --version && python -m timeit -s \
"import argparse; l = [argparse.Namespace(a=str(i)) for i in range(1000000)]" \
"''.join(obj.a for obj in l)"
Python 2.7.12
10 loops, best of 3: 87.2 msec per loop
python --version && python -m timeit -s \
"import argparse; l = [argparse.Namespace(a=str(i)) for i in range(1000000)]" \
"''.join([obj.a for obj in l])"
Python 2.7.12
10 loops, best of 3: 77.1 msec per loop
python3.4 --version && python3.4 -m timeit -s \
"import argparse; l = [argparse.Namespace(a=str(i)) for i in range(1000000)]" \
"''.join(obj.a for obj in l)"
Python 3.4.5
10 loops, best of 3: 77.4 msec per loop
python3.4 --version && python3.4 -m timeit -s \
"import argparse; l = [argparse.Namespace(a=str(i)) for i in range(1000000)]" \
"''.join([obj.a for obj in l])"
Python 3.4.5
10 loops, best of 3: 66 msec per loop
python3.5 --version && python3.5 -m timeit -s \
"import argparse; l = [argparse.Namespace(a=str(i)) for i in range(1000000)]" \
"''.join(obj.a for obj in l)"
Python 3.5.2
10 loops, best of 3: 82.8 msec per loop
python3.5 --version && python3.5 -m timeit -s \
"import argparse; l = [argparse.Namespace(a=str(i)) for i in range(1000000)]" \
"''.join([obj.a for obj in l])"
Python 3.5.2
10 loops, best of 3: 64.9 msec per loop
python3.6 --version && python3.6 -m timeit -s \
"import argparse; l = [argparse.Namespace(a=str(i)) for i in range(1000000)]" \
"''.join(obj.a for obj in l)"
Python 3.6.0
10 loops, best of 3: 84.6 msec per loop
python3.6 --version && python3.6 -m timeit -s \
"import argparse; l = [argparse.Namespace(a=str(i)) for i in range(1000000)]" \
"''.join([obj.a for obj in l])"
Python 3.6.0
10 loops, best of 3: 64.7 msec per loop
事实证明列表理解始终比生成器表达式更快:
但请注意,列表理解的内存消耗是2倍。
Dockerfile
您可以在硬件上运行以获得结果,例如docker build -t test-so . && docker run --rm test-so
。
FROM saaj/snake-tank
RUN echo '[tox] \n\
envlist = py27,py33,py34,py35,py36 \n\
skipsdist = True \n\
[testenv] \n\
commands = \n\
python --version \n\
python -m timeit -s \\\n\
"import argparse; l = [argparse.Namespace(a=str(i)) for i in range(1000000)]" \\\n\
"str().join(obj.a for obj in l)" \n\
python -m timeit -s \\\n\
"import argparse; l = [argparse.Namespace(a=str(i)) for i in range(1000000)]" \\\n\
"str().join([obj.a for obj in l])"' > tox.ini
CMD tox
答案 3 :(得分:2)
您可以将所有字符串属性转换为字符串列表:
string_list = [myobj.str for myobj in l]
上面的代码使用生成器创建字符串列表。之后你会使用标准方法来连接字符串:
"".join(string_list)
答案 4 :(得分:1)
列表理解可能会有所帮助。例如,有一个词典列表,
# data
data = [
{'str': 'a', 'num': 1},
{'str': 'b', 'num': 2},
]
joined_string = ''.join([item['str'] for item in data])
答案 5 :(得分:1)
以前的答案:
"".join([x.str_attr if hasattr(x,'str_attr_') else x for x in l ])
如果您的数据类型很简单。
''.join([somefunction(x) for x in l]) #
也看一下itertools模块。然后你可以检查对值的过滤。
答案 6 :(得分:1)
另一种可能性是使用函数式编程:
class StrObj:
def __init__(self, str):
self.str = str
a = StrObj('a')
b = StrObj('b')
c = StrObj('c')
l = [a,b,c]
"".join(map(lambda x: x.str, l))
这将以字符串可能连接到对象的任何方式工作(直接作为属性或以更复杂的方式)。只有lambda必须适应。
答案 7 :(得分:1)
自我解释的单行
"".join(str(d.attr) for d in l)