2016-04-26 109 views
1

我经常发现自己处于一种我想要迭代的逻辑连接符号组的情况。显而易见的解决方案是将这些符号添加到列表中,但是重复是一个需要维护的痛苦,我必须相信,如果我的同伴改变一个,他们也会改变另一个。Python:遍历一组符号

有没有办法在创建符号的同时将它们的值添加到列表中?

例如

# A group of like symbols that can be used independently in this scope 
hippo = 'hippo' 
gator = 'gator' 
mouse = 'mouse' 

# To loop across them I have to put them into a list 
valid_animals = [hippo, gator, mouse] # Maintain me separately, fool! 

伪代码,我想

# Data structure that declares symbols whose values can be iterated over 
valid_animals = { # Even your mom could maintain this 
    hippo = 'hippo' 
    gator = 'gator' 
    mouse = 'mouse' 
} 

# Use the symbols by themselves 
print "I had a", mouse, "in my house" 

# Iterate over the symbols 
print mouse in valid_animals # True 
+1

[Enum](https://docs.python.org/3/library/enum.html)是否适合您的需求? – rkersh

+0

枚举很棒,但有微妙但显着的差异。最值得注意的是,枚举集中在符号的名称上,而不是符号的值。迭代时这特别明显。例如,如果我将'valid_animals'更改为Enum,'valid_animals中的print mouse'将返回False。 – user2859458

+0

它可能不是你想要的,但是你可以在[i.value for i in valid_animals]中打印鼠标,对吧?而且,您可以添加一个'values'类方法,使其更漂亮一些(例如,在valid_animals.values()中打印鼠标)。 – rkersh

回答

0

@T。 Arboreus是对的;该解决方案是面向对象编程。为了在本地作用域中声明符号,同时将它们添加到迭代器中,我需要的只是一个追加动作的返回值,然后可以将它赋值给我的符号。

我通过继承list并添加bind方法做到了这一点。

# Iterable object that has a return on append 
class SymGroup(list): 
    def add(self, value): 
     self.append(value) 
     return value 



# Create my list that represents a group of symbol values 
valid_animals = SymGroup() 

# Assign and append values at the same time 
hippo = valid_animals.bind("hippo") 
gator = valid_animals.bind("gator") 
mouse = valid_animals.bind("mouse") 



# Symbol can be used by itself 
print "There is a", mouse, "in my house" 

# Can iterate across the symbol values 
print mouse in valid_animals # True 
print "horse" in valid_animals # False 

现在我只需要维护一个声明。

2

这听起来像面向对象编程是:

class Animal(object): 
    list = [] 
    def __init__(self,name): 
     self.name = name 
     Animal.list.append(self.name) 


mouse = Animal("mouse") 
cat = Animal("cat") 

print(mouse)  # <test.Animal object at 0x7f835e146860> 
print(mouse.name) # 'mouse' 
print(cat.name) # 'cat' 
print(Animal.list) # ['mouse', 'cat'] 

通常情况下,在Python,类有init方法。这看起来很神秘,但实际上只有一些基于类实例化对象时调用的代码。 (将该类视为创建对象的模板,并在创建对象时运行该方法。)

在类的内部,创建一个空列表。这是一个类级别的列表,可以在您的代码中通过Animal.list访问。它不与任何特定的实例化对象(即猫或鼠标)连接。

当调用init方法时,新创建的对象的名称将添加到类级别列表中。因此,如果您创建十个动物(动物('ocelot'),动物('袋鼠')等),您可以调用Animal.list查看所有动物的名称。

编辑:您请求您的问题更广泛的解决方案:

class Symbol(object): 
    types = [] 
    def __init__(self,name): 
     self.name = name 
     Symbol.types.append(self.name) 
     self.item_list = [] 


    def add(self,item): 
     self.item_list.append(item) 


animal = Symbol('animal') 

print(animal.item_list) # [] 

animal.add('tiger') 
animal.add('llama') 

print(animal.item_list) # ['tiger', 'llama'] 

food = Symbol('food') 

food.add('carrot') 
food.add('beans') 

print(food.item_list) # ['carrot', 'beans'] 

print(Symbol.types) # ['animal', 'food'] 
+0

使用类的值来存储列表是一个很好的主意,这解决了我的例子中的基本用例,但我正在寻找更通用的东西,可以在不需要每次创建新类时使用新类组。例如,如果除了动物组以外我还有一组食物符号,我需要一个班级来存储食物符号,以免让我的动物打起来。 – user2859458

+0

让我知道你对上述编辑的看法。 –

+0

新代码的问题是添加的动物现在不再是本地范围中的符号。 :(例如,我不能称为animal.tiger来获得“老虎”,但是,这是一个值得思考的好东西:) – user2859458

0

一个想法它只是维持名单:valid=['foo','bar','baz']

如果您为了方便起见想要定义同名变量,locals().update(zip(valid,valid))就可以做到这一点。

但是在严肃的项目中这肯定是一个坏主意。

+0

“本地人”可能无法正常工作:http://stackoverflow.com/a/8028772/4996248。这并不重要,尽管你肯定是正确的,在任何严肃的项目中这种事情都不是一个好主意。 –

+0

我只是在交互模式下使用它,当我厌倦了在密集的垃圾字符串操作中输入(并忘记了一些)倍数... ... –

0

我不知道这是任何一个大型项目是一个好主意,但你可以做到以下几点:

def varsFromStrings(*strings): 
    newVars = [] 
    for s in strings: 
     globals()[s] = s 
     newVars.append(s) 
    return newVars 

功能将一个字符串列表,创建变量对每个字符串,请输入这些变量放到globals字典中,并将字符串分配给每个变量,并返回字符串列表作为结果。那么即使你的妈妈可以输入:

valid_animals = varsFromStrings('hippo','gator','mouse') 

之后,

print("I had a", mouse, "in my house") 

for critter in valid_animals: print(critter) 

都工作正常。

这可能会对一些小型程序有所帮​​助,但是如果程序维护是一个问题 - 为什么不仅仅使用有效动物的常规字典呢?

+0

据我所知,字典是我在这里梦到的最接近的东西,但最终,字典键和符号是非常不同的野兽,并不完全相同。由于键必须是基元,它们通常最终会成为魔术字符串和数字,如果可能,我宁愿避免。此外,linting和其他代码智能工具对符号更有帮助。 – user2859458