关于python:如何通过while循环动态创建变量?

How can you dynamically create variables via a while loop?

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

我想通过Python中的while循环动态地创建变量。有人有什么创造性的方法来做这个吗?


除非有一个压倒性的需求来创建一堆变量名,否则我将使用一个字典,您可以在其中动态地创建键名并将值关联到每个键名。

1
2
3
4
5
6
7
8
9
a = {}
k = 0
while k < 10:
    <dynamically create key>
    key = ...
    <calculate value>
    value = ...
    a[key] = value
    k += 1

在新的"collections"模块中,还有一些有趣的数据结构可能适用:

http://docs.python.org/dev/library/collections.html网站


使用globals()可以:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import random

alphabet = tuple('abcdefghijklmnopqrstuvwxyz')


print '
'
.join(repr(u) for u in globals() if not u.startswith('__'))

for i in xrange(8):
    globals()[''.join(random.sample(alphabet,random.randint(3,26)))] = random.choice(alphabet)

print

print '
'
.join(repr((u,globals()[u])) for u in globals() if not u.startswith('__'))

一个结果是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'alphabet'
'random'

('hadmgoixzkcptsbwjfyrelvnqu', 'h')
('nzklv', 'o')
('alphabet', ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'))
('random', <module 'random' from 'G:\Python27\lib
andom.pyc'
>)
('ckpnwqguzyslmjveotxfbadh', 'f')
('i', 7)
('xwbujzkicyd', 'j')
('isjckyngxvaofdbeqwutl', 'n')
('wmt', 'g')
('aesyhvmw', 'q')
('azfjndwhkqgmtyeb', 'o')

我使用随机变量是因为你不解释要给出的"变量"的名称,也不解释要创建的值。因为我认为不将名称绑定到对象就无法创建名称。


使用exec()方法。例如,假设您有一个字典,并且您想要将每个键转换成一个具有其原始字典值的变量,可以执行以下操作。

Python 2

1
2
3
4
5
6
7
8
>>> c = {"one": 1,"two": 2}
>>> for k,v in c.iteritems():
...    exec("%s=%s" % (k,v))

>>> one
1
>>> two
2

Python 3

1
2
3
4
5
6
7
8
>>> c = {"one": 1,"two": 2}
>>> for k,v in c.items():
...    exec("%s=%s" % (k,v))

>>> one
1
>>> two
2


将内容填充到全局和/或本地命名空间不是一个好主意。使用听写是其他语言的一种…d['constant-key'] = value看起来很尴尬。Python是OO。用大师的话说:"名称空间是一个伟大的主意——让我们做更多的事情吧!"

这样地:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>> class Record(object):
...     pass
...
>>> r = Record()
>>> r.foo = 'oof'
>>> setattr(r, 'bar', 'rab')
>>> r.foo
'oof'
>>> r.bar
'rab'
>>> names = 'id description price'.split()
>>> values = [666, 'duct tape', 3.45]
>>> s = Record()
>>> for name, value in zip(names, values):
...     setattr(s, name, value)
...
>>> s.__dict__ # If you are suffering from dict withdrawal symptoms
{'price': 3.45, 'id': 666, 'description': 'duct tape'}
>>>


注意:这应该被视为一个讨论,而不是一个实际的答案。

一种近似的方法是在要创建变量的模块中操作__main__。例如,有一个b.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python
# coding: utf-8


def set_vars():
    import __main__
    print '__main__', __main__
    __main__.B = 1

try:
    print B
except NameError as e:
    print e

set_vars()

print 'B: %s' % B

运行它会输出

1
2
3
4
$ python b.py
name 'B' is not defined
__main__ <module '__main__' from 'b.py'>
B: 1

但是这种方法只在单个模块脚本中工作,因为它导入的__main__总是表示由python执行的入口脚本的模块,这意味着如果b.py与其他代码有关,那么B变量将在入口脚本的范围内创建,而不是在b.py本身中创建。假设有一个脚本a.py

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python
# coding: utf-8

try:
    import b
except NameError as e:
    print e

print 'in a.py: B', B

运行它会输出

1
2
3
4
5
$ python a.py
name 'B' is not defined
__main__ <module '__main__' from 'a.py'>
name 'B' is not defined
in a.py: B 1

注意,__main__改为'a.py'


关键字参数允许您将变量从一个函数传递到另一个函数。通过这种方式,您可以使用字典的键作为变量名(可以在您的while循环中填充)。调用字典名称时,只需在其前面加上**

1
2
3
4
5
6
7
8
9
10
11
12
# create a dictionary
>>> kwargs = {}
# add a key of name and assign it a value, later we'll use this key as a variable
>>> kwargs['name'] = 'python'

# an example function to use the variable
>>> def print_name(name):
...   print name

# call the example function
>>> print_name(**kwargs)
python

没有**kwargs只是一本字典:

1
2
>>> print_name(kwargs)
{'name': 'python'}


1
vars()['meta_anio_2012'] = 'translate'


免费DOM:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import random

alphabet = tuple('abcdefghijklmnopqrstuvwxyz')

globkeys = globals().keys()
globkeys.append('globkeys') # because name 'globkeys' is now also in globals()

print 'globkeys==',globkeys
print
print"globals().keys()==",globals().keys()

for i in xrange(8):
    globals()[''.join(random.sample(alphabet,random.randint(3,26)))] = random.choice(alphabet)
del i

newnames = [ x for x in globals().keys() if x not in globkeys ]
print
print 'newnames==',newnames

print
print"globals().keys()==",globals().keys()

print
print '
'
.join(repr((u,globals()[u])) for u in newnames)

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
globkeys== ['__builtins__', 'alphabet', 'random', '__package__', '__name__', '__doc__', 'globkeys']

globals().keys()== ['__builtins__', 'alphabet', 'random', '__package__', '__name__', 'globkeys', '__doc__']

newnames== ['fztkebyrdwcigsmulnoaph', 'umkfcvztleoij', 'kbutmzfgpcdqanrivwsxly', 'lxzmaysuornvdpjqfetbchgik', 'wznptbyermclfdghqxjvki', 'lwg', 'vsolxgkz', 'yobtlkqh']

globals().keys()== ['fztkebyrdwcigsmulnoaph', 'umkfcvztleoij', 'newnames', 'kbutmzfgpcdqanrivwsxly', '__builtins__', 'alphabet', 'random', 'lxzmaysuornvdpjqfetbchgik', '__package__', 'wznptbyermclfdghqxjvki', 'lwg', 'x', 'vsolxgkz', '__name__', 'globkeys', '__doc__', 'yobtlkqh']

('fztkebyrdwcigsmulnoaph', 't')
('umkfcvztleoij', 'p')
('kbutmzfgpcdqanrivwsxly', 'a')
('lxzmaysuornvdpjqfetbchgik', 'n')
('wznptbyermclfdghqxjvki', 't')
('lwg', 'j')
('vsolxgkz', 'w')
('yobtlkqh', 'c')

另一种方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import random

pool_of_names = []
for i in xrange(1000):
    v = 'LXM'+str(random.randrange(10,100000))
    if v not in globals():
        pool_of_names.append(v)

alphabet = 'abcdefghijklmnopqrstuvwxyz'

print 'globals().keys()==',globals().keys()

print
for j in xrange(8):
    globals()[pool_of_names[j]] = random.choice(alphabet)
newnames = pool_of_names[0:j+1]

print
print 'globals().keys()==',globals().keys()

print
print '
'
.join(repr((u,globals()[u])) for u in newnames)

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
globals().keys()== ['__builtins__', 'alphabet', 'random', '__package__', 'i', 'v', '__name__', '__doc__', 'pool_of_names']


globals().keys()== ['LXM7646', 'random', 'newnames', 'LXM95826', 'pool_of_names', 'LXM66380', 'alphabet', 'LXM84070', '__package__', 'LXM8644', '__doc__', 'LXM33579', '__builtins__', '__name__', 'LXM58418', 'i', 'j', 'LXM24703', 'v']

('LXM66380', 'v')
('LXM7646', 'a')
('LXM8644', 'm')
('LXM24703', 'r')
('LXM58418', 'g')
('LXM84070', 'c')
('LXM95826', 'e')
('LXM33579', 'j')