我试图通过随机生成家庭来自动填充城镇。我生成城镇名称,生成住户数,每个住户的姓氏和每个住户的人数。那很好。然而,我现在正在尝试创建每个人,生成名字,性别,年龄和职业,我也想将这些数据存储在一个列表中,一个列表包含每个人的属性。我遇到的问题是我想使用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循环创建的每个数组分配唯一的名称。名称是什么并不重要,只要每个人都有自己唯一命名的数组来存储他们的属性,它就可以是任何东西。
答案 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.name
和x.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]
正在存储当前房屋中的成员数量。
我会使用dictionary或named 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)
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)