我正在移植PHP中的一些代码,这些代码遍历一些数据库结果,并为棒球联盟的团队构建一个二维的输赢组。这是PHP中的代码
foreach ($results as $result) {
$home_team = $result['Game']['home_team_id'];
$away_team = $result['Game']['away_team_id'];
if (!isset($wins[$home_team][$away_team])) $wins[$home_team][$away_team] = 0;
if (!isset($wins[$away_team][$home_team])) $wins[$away_team][$home_team] = 0;
if (!isset($losses[$home_team][$away_team])) $losses[$home_team][$away_team] = 0;
if (!isset($losses[$away_team][$home_team])) $losses[$away_team][$home_team] = 0;
if ($result['Game']['home_score'] > $result['Game']['away_score']) {
$wins[$home_team][$away_team]++;
$losses[$away_team][$home_team]++;
} else {
$wins[$away_team][$home_team]++;
$losses[$home_team][$away_team]++;
}
}
$results
是一个包含数据库查询结果的数组
(编辑添加我已经拥有的Python代码)
现在我有了这个但是在Python中。 results
包含一系列Sqlalchemy结果对象
from sqlalchemy import Column, create_engine, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
engine = create_engine('postgresql://stats:st@ts=Fun@localhost/ibl_stats')
Session = sessionmaker()
Session.configure(bind=engine)
session = Session()
class Game(Base):
__tablename__ = 'games'
id = Column(Integer, primary_key=True)
week = Column(Integer)
home_score = Column(Integer)
away_score = Column(Integer)
home_team_id = Column(Integer, ForeignKey('franchises.id'))
away_team_id = Column(Integer, ForeignKey('franchises.id'))
class Franchise(Base):
__tablename__ = 'franchises'
id = Column(Integer, primary_key=True)
nickname = Column(String(3))
name = Column(String(50))
conference = Column(String(10))
division = Column(String(10))
ip = Column(Integer)
# Loop through our standings building up the breakdown results
results = session.query(Game).all()
wins = dict()
losses = dict()
for result in results:
home_team = result.home_team_id
away_team = result.away_team_id
if result.home_score > result.away_score:
wins[home_team][away_team] += 1
losses[away_team][home_team] += 1
else:
wins[away_team][home_team] += 1
losses[home_team][away_team] += 1
因此,当我运行此代码时,我收到以下错误:
(venv)vagrant@ibl:/vagrant/scripts$ python playoff_odds.py
Traceback (most recent call last):
File "playoff_odds.py", line 45, in <module>
wins[home_team][away_team] += 1
KeyError: 1
之前我做了一些搜索,它开始涉及“自动修复”的概念,这是PHP默认执行的操作,但Python没有。
那么如何在Python代码中复制相同的行为呢?
答案 0 :(得分:2)
Python's built-in dict class can be subclassed to implement autovivificious dictionaries simply by overriding the missing() method ,但这只是解决方案的一部分。如果您只是在维基百科链接中实现Tree
示例并执行以下操作:
wins = Tree()
wins['team_a']['team_b'] += 1
您遇到了TypeError: unsupported operand type(s) for +=: 'Tree' and 'int'
,因为wins['team_a']['team_b']
的示例代码也会自动输入Tree
。
鉴于:
wins = Tree()
wins['team_a']['team_b'] = 1
会正确分配值1(因为它是重新分配,而不是对现有类型值的操作)。
该解决方案将子类化以实现自动生成和,以确保叶元素是可以操作的整数。以下内容应该为您解决这个问题,或者至少让您开始:
以下内容应该有所帮助,或者至少可以帮助您:
from collections import defaultdict
def autovivify(levels=1, final=dict):
return (defaultdict(final) if levels < 2
else defaultdict(lambda: autovivify(levels - 1, final)))
wins = autovivify(2, int)
losses = autovivify(2, int)
wins['team_a']['team_b'] += 1
losses['team_b']['team_a'] += 1
wins['team_b']['team_c'] += 1
losses['team_c']['team_b'] += 1
wins['team_a']['team_c'] += 1
losses['team_c']['team_a'] += 1
wins['team_a']['team_b'] += 1
losses['team_b']['team_a'] += 1
print(wins['team_a']) # outputs defaultdict(<type 'int'>, {'team_b': 2, 'team_c': 1})
autovivify函数将确保第一个赋值(team_a
)将为您提供另一个自动生成树,第二个赋值(team_b
)将为您提供整数。从那里,您的+= 1
将继续增加0
的初始值。
答案 1 :(得分:1)
我想我可能会在这里使用namedtuples,但很难从这个片段中分辨出来。
如果您想了解如何编写更多Pythonic代码的材料,我建议您查看Raymond Hettinger的视频,特别是
&#34;美观易懂代码的最佳实践&#34;和 &#34;将代码转换为美丽的,惯用的Python&#34;:
答案 2 :(得分:1)
这个问题有很多解释。例如,我将使用以下字典模拟结果:
>>> result = {'Game':{'home_team':{'score':20,'id':1}, 'away_team':{'score':15,'id':2}}}
>>> print result['Game']
{'home_team': {'score': 20, 'id': 1}, 'away_team': {'score': 15, 'id': 2}}
>>> print result['Game']['home_team']
{'score': 20, 'id': 1}
>>> print result['Game']['away_team']['score']
15
有很多方法可以模拟你的代码,上面只是其中之一。当然,代码不会执行php代码所做的事情,只是显示了一种访问数据的方法。