从对象列表中连接字符串

时间:2017-06-15 14:06:03

标签: python string list object

我知道连接字符串列表的pythonic方法是使用

l =["a", "b", "c"]
"".join(l)

但是如果我有一个包含字符串(作为属性)的对象列表,而不重新分配字符串,我该如何做呢?

我想我可以实施__str__(self)。但这是我不愿意使用的解决方法。

8 个答案:

答案 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.7:快〜12%
  • 3.4:快〜15%
  • 3.5:快〜22%
  • 3.6:快〜24%

但请注意,列表理解的内存消耗是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)