python列表变量_关于列表:来自字符串的Python名称变量

本问题已经有最佳答案,请猛点这里访问。

是否可以基于字符串的值创建变量名?

我有一个脚本,它将读取一个文件中的信息块,并将它们存储在字典中。然后将每个块的字典附加到"master"字典中。文件中信息块的数量会有所不同,并使用"完成"一词来指示块的结尾。

我想这样做:

master={}

block=0

for lines in file:

if line !="done":

$block.append(line)

elif line =="done":

master['$block'].append($block)

block = block + 1

如果文件包含这样的内容:

eggs

done

bacon

done

ham

cheese

done

结果将是一本字典,有3个列表:

master = {'0': ["eggs"], '1': ["bacon"], '2': ["ham","cheese"]}

这是怎么做到的?

把你的字典变成了python字典。

在我看来,你似乎不需要字典,因为你正在使用从0开始的整数对字典项进行顺序索引。而是使用列表列表。

也许我不应该包括这个例子,但我仍然想知道是否有一种方法可以根据字符串的值(而不仅仅是字典键)来命名变量。

我真的建议你用列表来代替。有没有什么具体的点,为什么你需要数组式的听写?

如果可以使用数组,则可以使用以下命令:

with open("yourFile") as fd:

arr = [x.strip().split() for x in fd.read().split("done")][:-1]

输出:

[['eggs'], ['bacon'], ['ham', 'cheese']]

如果需要数字字符串索引,可以使用以下方法:

with open("yourFile") as fd:

l = [x.strip().split() for x in fd.read().split("done")][:-1]

print dict(zip(map(str,range(len(l))),l))

@投反对票的人:你能解释一下行动吗?

为什么有人投反对票?在我看来,它比其他答案更正确,因为它不仅回答了问题,而且提供了比OP预期更优雅的数据结构。

@劳弗尔:我没抓到你。什么??

我同意这一点,一个列表是一个更好的数据结构-我实际上正在为我的答案写一个类似的想法。这就是说,我觉得你的第二部分很难看——如果你想要听写,按照我的方法,在列表中,按照第一个thrustmaster的方法。

@Thrustmaster:不过,我建议您用for循环来构造您的应答代码,因为OP似乎已经比较适合使用这种流控制语法了。更简洁并不一定更好,尤其是当涉及到列表理解和生成器表达式时。

@亚瑟,我不认为这意味着你应该放弃更恰当(并且在所有方面都更好)的清单理解。

@弗朗西斯:是的,我明白。但是,建议一种更易读、更简洁、更为Python式的做事方式有什么坏处吗?

不幸的是,列表理解泄漏了一个文件引用。(旁注:我认为从itertools.count获得回报时打电话给str比getnextnumber要干净得多。)

@朋友们:我不是想建议你们不要把自己的清单包括在内,不要说它是正确的做事方式。然而,由于对于初学者来说,这种语法通常不熟悉或不直观,所以我通常额外提供类似的for循环版本,供初学者参考。

@DSM一般来说,字典的一个更干净的解决方案是一个简单的带有defaultdict的循环。

@DSM:谢谢你指出这一点。当我试图使它紧凑的时候,我没有想到这一点。:)

你似乎误解了字典的工作原理。他们拿的钥匙是物体,所以这里不需要魔法。

但是,我们可以使用collections.defaultdict根据需要制作子列表,从而使您的代码更好。

from collections import defaultdict

master = defaultdict(list)

block = 0

for line in file:

if line =="done":

block += 1

else:

master[block].append(line)

不过,我建议,如果你想要连续的、有编号的索引,字典是不必要的——这就是列表的目的。在这种情况下,我建议您遵循Thrustmaster的第一个建议,或者作为一个替代方案:

from itertools import takewhile

def repeat_while(predicate, action):

while True:

current = action()

if not predicate(current):

break

else:

yield current

with open("test") as file:

action = lambda: list(takewhile(lambda line: not line =="done", (line.strip() for line in file)))

print(list(repeat_while(lambda x: x, action)))

我认为"完成"的分裂注定要失败。考虑以下列表:

eggs

done

bacon

done

rare steak

well done stake

done

从Thrustmaster偷东西(我偷东西给了+1),我建议:

>>> dict(enumerate(l.split() for l in open(file).read().split('

done

') if l))

{0: ['eggs'], 1: ['bacon'], 2: ['ham', 'cheese']}

我知道这需要一个尾随的""。如果有问题,可以使用"open(file.read()+''"或甚至"+'行'",如果最后完成是可选的。

这是您的代码,用于并列:

master={}

block=0

for lines in file:

if line !="done":

$block.append(line)

elif line =="done":

master['$block'].append($block)

block = block + 1

正如ThrustMaster在文章中提到的,在这里使用嵌套列表更有意义。以下是您将如何做到这一点的方法;我在结构上尽可能少地更改了您的原始代码:

master=[[]] # Start with a list containing only a single list

for line in file: # Note the typo in your code: you wrote"for lines in file"

if line !="done":

master[-1].append(line) # Index -1 is the last element of your list

else: # Since it's not not"done", it must in fact be"done"

master.append([])

这里唯一的一点是,在您的EDOCX1[1]列表的末尾会有一个额外的列表,因此您应该在EDOCX1[2]中添加一行,以检测最后一个空子列表:

del master[-1]

使用setattr或globals()。请参阅如何在当前模块上调用setattr()?

读一读这个问题,其实这不是他要问的。

事实上,如果是这样的话,你的答案是正确的,所以我将把那个留在这里,投票给你。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值