如何遍历Python列表并对该列表的元素进行数学计算?

时间:2019-01-02 11:55:28

标签: python

我正在尝试创建一个合同桥梁匹配点计分系统。在下面的列表中,第一,第三等数字是对数(玩家),第二,第四等数字是每对获得的分数。因此,配对2得分430,配对3得分420,依此类推。

我想遍历列表并得分如下:

对于每对2拍获胜的得分,他们获得2分,对每1分,他们获得1分;如果不打败,则获得0分。然后循环继续,并以相同的方式比较每对分数。在下面的示例中,对2获得7分(击败其他3对,并与1并列),对7获得0分,对6获得12分,每隔两对击败。

我的列表(从elasticsearch json对象生成)是:

['2', '430', '3', '420', '4', '460', '5', '400', '7', '0', '1', '430', '6', '480']

我尝试过的python代码(经过多次修改)是:

nsp_mp = 0
ewp_mp = 0
ns_list = []
for row in arr["hits"]["hits"]:
  nsp = row["_source"]["nsp"]
  nsscore = row["_source"]["nsscore"]
  ns_list.append(nsp)
  ns_list.append(nsscore)

print(ns_list)
x = ns_list[1]
for i in range(6):  #number of competing pairs
  if x > ns_list[1::2][i]:
    nsp_mp = nsp_mp + 2
  elif x == ns_list[1::2][i]:
    nsp_mp = nsp_mp
  else: 
    nsp_mp = nsp_mp + 1
print(nsp_mp)

产生:

['2', '430', '3', '420', '4', '460', '5', '400', '7', '0', '1', '430', '6', '480']
7

根据上面的计算是正确的。但是,当我尝试执行循环时,它不会返回正确的结果。

也许这种方法是错误的。正确的方法是什么?

elasticsearch json对象为:

arr = {'took': 0, 'timed_out': False, '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0}, 'hits': {'total': 7, 'max_score': 1.0, 'hits': [{'_index': 'match', '_type': 'score', '_id': 'L_L122cBjpp4O0gQG0qd', '_score': 1.0, '_source': {'tournament_id': 1, 'board_number': '1', 'nsp': '2', 'ewp': '9', 'contract': '3NT', 'by': 'S', 'tricks': '10', 'nsscore': '430', 'ewscore': '0', 'timestamp': '2018-12-23T16:45:32.896151'}}, {'_index': 'match', '_type': 'score', '_id': 'MPL122cBjpp4O0gQHEog', '_score': 1.0, '_source': {'tournament_id': 1, 'board_number': '1', 'nsp': '3', 'ewp': '10', 'contract': '4S', 'by': 'N', 'tricks': '10', 'nsscore': '420', 'ewscore': '0', 'timestamp': '2018-12-23T16:45:33.027631'}}, {'_index': 'match', '_type': 'score', '_id': 'MfL122cBjpp4O0gQHEqk', '_score': 1.0, '_source': {'tournament_id': 1, 'board_number': '1', 'nsp': '4', 'ewp': '11', 'contract': '3NT', 'by': 'N', 'tricks': '11', 'nsscore': '460', 'ewscore': '0', 'timestamp': '2018-12-23T16:45:33.158060'}}, {'_index': 'match', '_type': 'score', '_id': 'MvL122cBjpp4O0gQHUoj', '_score': 1.0, '_source': {'tournament_id': 1, 'board_number': '1', 'nsp': '5', 'ewp': '12', 'contract': '3NT', 'by': 'S', 'tricks': '10', 'nsscore': '400', 'ewscore': '0', 'timestamp': '2018-12-23T16:45:33.285460'}}, {'_index': 'match', '_type': 'score', '_id': 'NPL122cBjpp4O0gQHkof', '_score': 1.0, '_source': {'tournament_id': 1, 'board_number': '1', 'nsp': '7', 'ewp': '14', 'contract': '3NT', 'by': 'S', 'tricks': '8', 'nsscore': '0', 'ewscore': '50', 'timestamp': '2018-12-23T16:45:33.538710'}}, {'_index': 'match', '_type': 'score', '_id': 'LvL122cBjpp4O0gQGkqt', '_score': 1.0, '_source': {'tournament_id': 1, 'board_number': '1', 'nsp': '1', 'ewp': '8', 'contract': '3NT', 'by': 'N', 'tricks': '10', 'nsscore': '430', 'ewscore': '0', 'timestamp': '2018-12-23T16:45:32.405998'}}, {'_index': 'match', '_type': 'score', '_id': 'M_L122cBjpp4O0gQHUqg', '_score': 1.0, '_source': {'tournament_id': 1, 'board_number': '1', 'nsp': '6', 'ewp': '13', 'contract': '4S', 'by': 'S', 'tricks': '11', 'nsscore': '480', 'ewscore': '0', 'timestamp': '2018-12-23T16:45:33.411104'}}]}}

4 个答案:

答案 0 :(得分:1)

列表似乎不是一个很好的数据结构,我认为您通过展平Elasticsearch对象使一切变得更糟。

  

请注意下面的列表中有一些小错误-请确保   我不是免费解决某人的作业。我也意识到这是   不是最有效的方法。

尝试使用字典:

1)将您拥有的elasticsearch json转换为结构更好的字典:

scores = {}
for row in arr["hits"]["hits"]:
  nsp = row["_source"]["nsp"]
  nsscore = row["_source"]["nsscore"]
  scores[nsp] = nsscore

这会给你这样的东西:

{'1': '430',
 '2': '430',
 '3': '420',
 '4': '460',
 '5': '400',
 '6': '480',
 '7': '0'}

2)编写一个计算对分数的函数:

def calculate_score(pair, scores):
    score = 0
    for p in scores:
        if p == pair:
            continue
        if scores[p] < scores[pair]:
            score += 2  # win
        elif scores[p] == scores[pair]:
            score += 1
    return score

这应该给你这样的东西:

In [13]: calculate_score('1', scores)
Out[13]: 7

In [14]: calculate_score('7', scores)
Out[14]: 0

3)遍历所有对,计算分数。我将把它保留为练习。

答案 1 :(得分:0)

您的代码的主要问题是,循环很短,您有7个条目。然后,您应该将数字转换为int,以便比较正确。在您的代码中,平局得到0分。 您应该使用元组对代替具有扁平对的列表。

ns_list = []
for row in arr["hits"]["hits"]:
    nsp = int(row["_source"]["nsp"])
    nsscore = int(row["_source"]["nsscore"])
    ns_list.append((nsp, nsscore))

print(ns_list)
x = ns_list[0][1]
nsp_mp = 0
for nsp, nsscore in ns_list:
    if x > nsscore:
        nsp_mp += 2
    elif x == nsscore:
        nsp_mp += 1
print(nsp_mp)

答案 2 :(得分:0)

所以我们可以这样做:

import itertools

d = [(i['_source']['nsp'], i['_source']['nsscore']) for i in arr['hits']['hits']]

d

[('2', '430'),
 ('3', '420'),
 ('4', '460'),
 ('5', '400'),
 ('7', '0'),
 ('1', '430'),
 ('6', '480')]

c = itertools.combinations(d, 2)

counts = {}
for tup in c:
    p1, p2 = tup
    if not counts.get(p1[0]):
        counts[p1[0]] = 0
    if int(p1[1]) > int(p2[1]):
        counts[p1[0]] += 1

counts

{'2': 3, '3': 2, '4': 3, '5': 1, '7': 0, '1': 0}

答案 3 :(得分:0)

我首先使用itertools将您的乐谱列表转换为字典对象,然后遍历每个键,并针对每个键比较列表中可用的值 并相应地添加您提供的得分,由于在这种方法中您将始终添加值1,因为您将始终将其与自身进行比较,因此最终i比最终得分降低1时,可能会有更好的方法

ls = ['2', '430', '3', '420', '4', '460', '5', '400', '7', '0', '1', '430', '6', '480']
d = dict(itertools.zip_longest(*[iter(ls)] * 2, fillvalue=""))
values= d.values()
for item in d.keys():
   score=0
   for i in values:
     if d[item]>i:
       score+=2
     elif d[item]==i:
       score+=1
     else:
       pass
   print(item,":",score-1)

输出:

2 : 7
3 : 4
4 : 10
5 : 2
7 : 0
1 : 7
6 : 12