(Python)使用唯一自动生成的名称创建列表

时间:2012-03-15 02:52:16

标签: python list

我试图通过随机生成家庭来自动填充城镇。我生成城镇名称,生成住户数,每个住户的姓氏和每个住户的人数。那很好。然而,我现在正在尝试创建每个人,生成名字,性别,年龄和职业,我也想将这些数据存储在一个列表中,一个列表包含每个人的属性。我遇到的问题是我想使用for循环,例如:

    #houseArray[currentFam][1] is the number of members in the current house. 
    for currentFam in range(houseArray[currentFam][1]):
        uniquelyNamedArray[0] = genSex()
        uniquelyNamedArray[1] = genFirstName()
        uniquelyNamedArray[2] = genAge()

所以...看看第一个家庭的数据,使用for循环迭代每个成员分配统计数据,然后转到下一个家庭并做同样的事情,在每个家庭中进行。我的问题在于不知道如何为for循环创建的每个数组分配唯一的名称。名称是什么并不重要,只要每个人都有自己唯一命名的数组来存储他们的属性,它就可以是任何东西。

5 个答案:

答案 0 :(得分:5)

使用以人名作为关键字的字典。像:

people = {}
people["Billy Bloggs"] = ['23','Male','263 Evergreen Tce'] # store to dict
print ( people["Billy Bloggs"] ) # get stuff out of dict

更好的是,通过将属性名称存储为dict来提供属性名称:

people["Billy Bloggs"] = { 'Age':23, 'Gender':'M', 'Address':'263 Evergreen Tce' }
print ( people["Billy Bloggs"]['Age'] ) # Get billy's age

您可以使用以下语法遍历字典的元素:

>>> mydict = {'a':'Apple', 'b':'Banana', 'c':'Cumquat'}
>>> for key, value in mydict.iteritems():
...     print ('Key is :' + key + ' Value is:' + value)
... 
Key is :a Value is:Apple
Key is :c Value is:Cumquat
Key is :b Value is:Banana

请注意,无法保证数据的顺序。您可以按A, B, C的顺序插入数据并返回A, C, B

注意:dict的键(在本例中为人名)被限制为唯一。因此,如果您将数据存储为相同名称两次,则第一个键:值对将被覆盖

mydict["a"] = 5
mydict["a"] = 10
print (mydict["a"]) # prints 10

旁注:您的gen*()部分功能几乎肯定会被random.choice()取代:

import random
first_names = ['Alice','Bob','Charlie','Dick','Eliza']
random_first_name = random.choice(first_names)

答案 1 :(得分:2)

将程序数据与变量名混合。可以将变量称为通用变量;你一直这样做:例如在你的for循环中,你使用currentFam而不是家庭的名字。要求对数组进行唯一命名会使得(没有冒犯)与询问名称currentFam(无论你的名字无关)或者尝试做什么都有意义:

Andersons[0] = genSex()
Andersons[1] = genFirstName()
Andersons[2] = genAge()
Longs[0] = genSex()
Longs[1] = genFirstName()
Longs[2] = genAge()
Smiths[0] = genSex()
Smiths[1] = genFirstName()
Smiths[2] = genAge()
...

变量与程序数据分开。


您应该只为数组person命名,并将其与其他数组一起存储。更好的方法是定义class Person(object): ...,这样您就可以执行x.namex.age之类的操作,但您不需要这样做。例如:

class Person(object):
    def __init__(self, **kw):
        self.data = kw
        self.__dict__.update(kw)
    def __repr__(self):
        return str('Person(**{})'.format(self.data))
    __str__ = __repr__

M = Person.M = 'm'
F = Person.F = 'f'

ALL_PEOPLE = set()
for ...:
    person = Person(name=..., age=..., sex=...)
    people.add(person)

然后找人:

def findPeople(name=None, age=None, custom=set()):
    matchers = custom
    if name!=None:
        matchers.add(lambda x:name.lower() in x.name.lower())
    if age!=None:
        matchers.add(lambda x:age==x.age)

    return set(p for p in ALL_PEOPLE if all(m(p) for m in matchers))

演示:

ALL_PEOPLE = set([
 Person(name='Alex', age=5, sex=M),
 Person(name='Alexander', age=33, sex=M),
 Person(name='Alexa', age=21, sex=F)
])

>>> pprint.pprint( findPeople(name='alex', custom={lambda p: p.age>10}) )
{Person(**{'age': 33, 'name': 'Alexander', 'sex': 'm'}),
 Person(**{'age': 21, 'name': 'Alexa', 'sex': 'f'})}

答案 2 :(得分:2)

Keep data out of your variable names并将它们存储在dict

答案 3 :(得分:2)

首先,虽然您没有向我们展示周围的代码,但您可能过分依赖全局变量。而不是尝试为每个家庭成员创建唯一命名的数组,只需执行以下操作:

不要真的这样做(我会在一分钟内告诉你原因)

#houseArray[currentFam][1] is the number of members in the current house. 
for currentFam in range(houseArray[currentFam][1]):
    family_member_info = []
    family_member_info[0] = genSex()
    family_member_info[1] = genFirstName()
    family_member_info[2] = genAge()
    # Pretend 2 is where we are storing the family member information list
    houseArray[currentFam][2].append(family_member_info)

更好的方法

不要将数组用于此类事情 - 很快就会很难判断实际存储在哪个索引中的内容。即使在您的示例中,您也必须注意houseArray[currentFam][1]正在存储当前房屋中的成员数量。

我会使用dictionarynamed tuple并将您的信息存储在那里。这样你就可以做到这样的事情:

from collections import namedtuple

# Create a class called "household"
# with three fields, "owner", "size" and "members"
household = namedtuple("household", "owner size members")

househould_array = []
# Create some households and put them in the array
household_array.append(household("Family #1", 3, []))
household_array.append(household("Family #2", 1, []))
household_array.append(household("Family #3", 7, []))

# Loop over every household in the household_array
for family in household_array:
    # Each `household` namedtulpe's values can be accessed by
    # attribute as well as by index number
    # family[1] == family.size == 3
    # (for Family #1)
    for member_number in range(family.size):
        # family[2] == family.members == []
        # (before we put anything in it)
        family.members.append(generate_family_member())

答案 4 :(得分:0)

哇,我非常喜欢阅读所有其他答案 这么多很棒的建议包括但不限于:

  • @Sean Vieira建议命名元组 - 一个优秀,轻量级的选择;
  • @ninjagecko使用一个巧妙的技巧来动态分配实例属性;
  • @ Li-aung Yip使用内置的sqlite3模块提及。

如果不是所有的内容都已被提出,那么很多 如果没有别的,我希望这个答案能够介绍除了其他数据结构提供的类之外可以提供哪些类。

警告:如果表现是一个巨大的问题,那么将每个实体建模为一个类可能会有点过分。

from __future__ import division, print_function

class Town(object):
    def __init__(self, name=None, country=None, area_km2=0, population=0):
        self.name = name 
        self.area_km2 = area_km2
        self.area_mi2 = self.area_km2 * 0.38610217499077215
        self.population = population
        self.households = []

    @property
    def total_households(self):
        return len(self.households)

    @property
    def population_density_per_km2(self):
        try: 
            return self.population / self.area_km2
        except ZeroDivisionError: 
            return 0

    @property
    def population_density_per_mi2(self):
        try: 
            return self.population / self.area_mi2
        except ZeroDivisionError: 
            return 0

class Household(object):
    def __init__(self, primary_lang='Esperanto'):
        self.primary_lang = primary_lang
        self.members = []

    @property
    def total_members(self):
        return len(self.members)

class Person(object):
    def __init__(self, age=0, gender=None, first_name=None):
        self.age = age
        self.gender = gender
        self.first_name = first_name

if __name__ == '__main__':
    londontown = Town(name='London', 
                      country='UK', 
                      area_km2=1572,
                      population=7753600)

    print(londontown.population_density_per_km2)
    print(londontown.population_density_per_mi2)

    a_household = Household()
    a_household.members.append(
        Person(age=10, gender='m', first_name='john'),
    )
    a_household.members.append(
        Person(age=10, gender='f', first_name='jane')
    )

    londontown.households.append(a_household)
    print(londontown.total_households)
    print(a_household.total_members)