如何将包含3个数据(在相邻列中)的名称的CSV文件转换为创建的类的变量,该类将相邻的数据作为参数?
下面的代码似乎是为了创建对象,但列表是对象位置而不是我想要的名称。
有人可以帮忙吗?
class Teams(object):
def __init__(self, TeamName, FT, FG, Three):
self.TeamName = TeamName
self.FT = FT
self.FG = FG
self.Three = Three
North_Carolina = Teams("North Carolina", .643,.458,.371)
print North_Carolina.TeamName, North_Carolina.FT, North_Carolina.FG,North_Carolina.Three
## works fine but manually typed data
def getData(fname): ##fname is a csv file with 4 columns and 348 rows. One header row.
Data = open(fname, 'r')
TeamList = []
#print Data.read() ## prints a list with comma separated values and line return
for line in Data:
info = line.split(",") ##info is a list of lists of Data with Team,FT,FG,3P
name = info[0]
FT = info[1]
FG = info[2]
Three = info[3]
newTeam = (name, FT, FG, Three)
newTeam2 = Teams(newTeam[0],newTeam[1],newTeam[2],newTeam[3]) ##newTeam2 is an object.
TeamList.append(newTeam2)
print TeamList[1].TeamName ##prints North Carolina list[0] print header
print TeamList #prints list of object locations but not objects themselves
getData("Stats 01-04-2013.csv")
第一个print
语句打印:
North Carolina
第二个print
语句打印:
[<__main__.Teams object at 0x02953230>, <__main__.Teams object at 0x029532B0>, etc etc
答案 0 :(得分:1)
对象位置 对象的打印方式。严格来说,在列表中每个元素的str
调用repr
上调用list
或repr
。默认情况下,repr(team)
对象上的Teams
将返回<main.Teams object at 0x02953230>
之类的内容。您可以通过在__repr__
类上定义Teams
方法来覆盖它。但是,这听起来不像你想要的那样。
如果TeamList
是Teams
个对象的列表,并且您想将其转换为TeamName
个成员的列表,则只需使用list comprehension
进行转换即可:
TeamNameList = [team.TeamName for team in TeamList]
请注意,这仍然不是您想要打印出来的:
>>> print TeamNameList
['North Carolina', 'South Carolina', 'West Carolina', 'East Carolina', 'Underground Carolina', 'Cloud-level Carolina', 'Past Carolina', 'Future Carolina'] # those are all states, right?
你可能想要这样的东西:
>>> print ', '.join(TeamNameList)
North Carolina, South Carolina, West Carolina, East Carolina, Underground Carolina, Cloud-level Carolina, Past Carolina, Future Carolina
来自您的评论:
后来有一个函数simGame(teamA,Teamb)
我看到了实例,但是我不知道如何在第二个函数中调用它们。我曾打算用名字给他们打电话。在我给出的示例中,North_carolina可以传递给后者(未显示的函数),并且可以对数据运行计算
我想我明白你想要什么。您希望能够模拟北卡罗来纳州和南卡罗来纳州之间的游戏,只需拥有TeamList
。
为此,您可能想要创建dict
,将名称映射到Teams
对象,如下所示:
TeamDict = {team.TeamName: team for team in TeamList}
现在,您可以这样做:
simGame(TeamDict['North Carolina'], TeamDict['South Carolina'])
现在,simGame
将Teams
类的北卡罗来纳州和南卡罗来纳州的实例作为其teamA
和teamB
参数,因此它可以执行以下操作: :
def simGame(teamA, teamB):
scoreA = int(teamA.FT * 1 * 20) + int(teamA.FG * 2 * 40) + int(teamA.Three * 3 * 10)
scoreB = int(teamB.FT * 1 * 20) + int(teamB.FG * 2 * 40) + int(teamB.Three * 3 * 10)
if scoreA > scoreB:
print 'Home team {} beats visitor {} by {}!'.format(teamA.TeamName,
teamB.TeamName,
scoreA - scoreB)
else:
print 'Visitors {} win by {} over {} at home!'.format(teamB.TeamName,
scoreB - scoreA,
teamA.TeamName)
这就是你想要的吗?
其他一些评论:
您也可以使用map
执行与列表推导相同的操作,这样可以避免必须两次编写team
,但这也意味着您无法使用正常的表达式语法:
TeamNameList = map(operator.attrgetter('TeamName'), TeamList)
或者您可以将map
与lambda
一起使用以取回表达式语法...并重复team
:
TeamNameList = map(lambda team: team.teamName, TeamList)
但是对于这样的情况,列表理解通常被认为是做到这一点的pythonic方式。 (另外,如果你去Python 3,它不会改变,而map
从list
更改为迭代器,这意味着print TeamNameList
会给你<builtins.map at 0x108022350>
之类的东西......但', '.join(TeamNameList)
仍然可以使用。)
作为旁注,在标准(PEP 8)Python样式中,通常只有类在TitleCase中,而变量和属性在lower_case中。如果您真的喜欢CamelCase,那么您可以使用lowerFirstCamelCase,但使用TitleCase会让人们阅读您的代码,他们将立即尝试找出TeamName
类的定义位置。另请参阅bvukelic的评论。
另一方面,你似乎做了很多重复的代码,我不确定原因:
name = info[0]
FT = info[1]
FG = info[2]
Three = info[3]
newTeam = (name, FT, FG, Three)
您只是将info
复制到newTeam
;为什么要添加所有那些永远不会再次使用的中间变量?
newTeam2 = Teams(newTeam[0],newTeam[1],newTeam[2],newTeam[3])
你可以用以下方式替换所有这些:
newTeam2 = Teams(info[0],info[1],newTeam[2],newTeam[3])
甚至:
newTeam2 = Teams(*info)
如果你需要在某个你没有向我们展示的单独变量,那很好,但你仍然不可能需要newTeam
;这样做:
newTeam2 = Teams(name, FT, FG, Three)
答案 1 :(得分:1)
我会使用csv模块执行类似的操作,主要基于module documentation中的示例。可能需要调整,这只是我的头脑,但在处理这些类型的文件时我总是使用相关的。
import csv
with open('teams.csv', 'rb') as csvfile:
teamreader = csv.reader(csvfile)
for row in teamreader:
newTeam = Teams(row[0], row[1], row[2], row[3])
teamList.append(newTeam)
答案 2 :(得分:0)
只是为了解释这个问题的另一种解释:
class Teams(object):
def __init__(self, TeamName, FT, FG, Three):
self.TeamName = TeamName
self.FT = FT
self.FG = FG
self.Three = Three
def __str__(self):
return str(self.TeamName)
def __repr__(self):
return self.__unicode__()
每当您打印对象时,它都会显示为TeamName
答案 3 :(得分:0)
如何显示类实例是通过为其提供自定义__str__()
和/或__repr__()
转换方法来控制的。这是编写代码的一种方式,并使其遵循PEP 8 Style Guide中的许多建议。您也可以使用csv
模块阅读文件来改进或简化它,如其他人已经建议的那样,但我会主要关注您问题中显示的代码。
class Team(object):
def __init__(self, team_name, free_throws, field_goals, three_pointers):
self.team_name = team_name
self.free_throws = free_throws
self.field_goals = field_goals
self.three_pointers = three_pointers
def __repr__(self):
return '{}({!r}, {}, {}, {})'.format(self.__class__.__name__,
self.team_name, self.free_throws,
self.field_goals, self.three_pointers)
def get_data(fname): # fname is a csv file with 4 columns and one header row
teams = []
with open(fname, 'rt') as csv_file:
csv_file.next() # skip header row
for line in csv_file:
info = line.strip().split(",")
teams.append(Team(*info)) # create a Team instance and add it to list
return teams
print get_data("Stats 01-04-2013.csv")
示例输出:
[Team('North Carolina', .643, .458, .371), Team('Michigan', .543, .358, .271)]