【问题标题】:Convert string representation of tuple to dict将元组的字符串表示形式转换为 dict
【发布时间】:2018-01-08 11:00:07
【问题描述】:

我有一个string 代表tuple,如下所示:

t = "(a,b),(c,d),(e,f)"

我想把它转换成这样的字典:

d = {'a':'b', 'c':'d', 'e':'f'}

我尝试按照以下方式进行操作

>>> l = t.split(',')
>>> l
>>> ['(a', 'b)', '(c', 'd)', '(e', 'f)']

>>> l = [i.replace('(','').replace(')','') for i in l]
>>> l
>>> ['a', 'b', 'c', 'd', 'e', 'f']

>>> dict([(a,b) for a,b in zip(l[::2],l[1::2])])
>>> {'e': 'f', 'c': 'd', 'a': 'b'}

这给了我正确的结果(dict 元素的顺序对我来说并不重要)。然而,这是低效的,因为它需要三个步骤才能获得所需的输出。有没有办法在两个或理想的一个操作/语句中得到这个?

【问题讨论】:

  • 您应该在尝试改进之前测量性能。这样您就可以知道是否有必要以及是否实现了速度提升。
  • @GarbageCollector t 是由逗号分隔的许多元组的字符串表示形式。
  • @Chris_Rands 在 Python 中它们不是必需的。
  • 关于变量名...是的,它们需要被定义,就像我上面的评论一样。
  • @user202729 需要定义哪些变量名?

标签: python-3.x dictionary tuples


【解决方案1】:

正如我在 cmets 中已经说过的:

  • 更少的代码并不总是意味着代码运行得更快。
  • 如果它不是性能关键,那么优化它就不是很重要。
  • 性能已经相当快了。

但是,代码执行了一个冗余步骤:当您只需要从已知位置删除一个字符时,为什么还要使用replace?

在这里,我编写了一些执行相同任务的函数。

随机导入

random.seed(1234)

def f():
    return ''.join(chr(random.randint(65,90)) for _ in range(100))

def g():
    return ','.join('({}, {})'.format(f(), f()) for _ in range(1000))

def ext(t):
    l = t.split(',')
    l = [i.replace('(','').replace(')','') for i in l]
    return dict([(a,b) for a,b in zip(l[::2],l[1::2])])

def ext2(t):
    l = t.split(',')
    return dict([(a[1:],b[:-1]) for a,b in zip(l[::2],l[1::2])])

def ext3(t):
    l = t.split(',')
    return {a[1:] : b[:-1] for a,b in zip(l[::2],l[1::2])}

def ext4(t):
    return dict(x.split(',') for x in t[1:-1].split('),('))

import timeit

t = g()
assert(ext(t) == ext2(t) == ext3(t) == ext4(t))

print(len(t))
print(timeit.timeit(lambda: ext (t), number=30))
print(timeit.timeit(lambda: ext2(t), number=30))
print(timeit.timeit(lambda: ext3(t), number=30))
print(timeit.timeit(lambda: ext4(t), number=30))

Try it online!

如 TIO 所示,函数 ext3 的执行时间最短,与 OP 的原始函数 ext 相比,速度提高了 2 倍。

ext4 不比ext3 快(尽管仍然比ext 快),因为它避免了replace,但它是一种说法。仅对代码高尔夫有用。实际上,有多少语句并不重要。

附上运行上述代码的结果,因为答案应该是自包含的:

204999
0.05400996300159022
0.022308056009933352
0.02011037600459531
0.02612137998221442

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 2015-12-19
    • 2022-01-19
    • 2019-12-03
    • 2021-02-20
    • 2023-03-03
    相关资源
    最近更新 更多