【问题标题】:Removing Text and Comparing Integers within Strings删除文本并比较字符串中的整数
【发布时间】:2015-09-29 23:33:49
【问题描述】:

由于我的原始帖子充满了煽动者,假设我要求他们为我编写代码并且根本拒绝回答我,所以我重新发布了我的问题。

我强调我是 Python 的初学者,我不是在这里要求人们为我编写它,我只是想确定方法和一些关于如何解决问题的指导,因为我很难接近它,而且每个人似乎都认为我是在要求他们给我我需要的所有代码,而我没有。

那么,回到我原来的问题。

我的问题如下,我做了一个数学测验,将名字和分数输出到一个文本文件。在这个程序中,我计划在开头添加一些代码,它将运行一个选项列表来比较和排序来自文本文件的结果。程序将条目导入列表,格式如下:

['约翰:6','鲍勃:9','比利:2','马修:7','吉米:2','艾米:9','珍妮:10','迈克尔:8 ']

Python 将此列表识别为 8 个项目,非常完美。它有他们的名字,然后是他们的分数。问题是我正在努力的规范要求我能够:

按字母顺序排列每个学生的考试最高分。

同样,按最高分,最后按平均分。我已经尝试了很多小时,以找到一些可以将这些字符串中的整数相互比较以找到最高分的代码,并且只打印那个,但我没有运气。我觉得我也会在其他 2 项任务中遇到困难,希望得到一些指导。

我考虑过可能使用切片来将整数转换为单独的值以便比较它们,但觉得这可能会使代码很快变得混乱。

【问题讨论】:

  • 名单可以有同名的学生吗?
  • 可以,一定能识别出整数最大的条目。
  • 所以你想要的是1)按名称排序,然后按分数(如果两个或多个元素具有相同的名称;2)按分数排序; 3)这个是我没有得到的,你要得到所有分数的平均分吗?
  • 按字母顺序排序,如果同一个人有 2 个条目,则应仅打印该学生的最高条目 2) 按分数排序,取其最高值并忽略其他条目 3) 如果更多比同一学生的一个条目,计算他们的平均分数,然后将每个学生的平均分数从高到低排序
  • 这样更有意义吗?

标签: python string python-3.x integer


【解决方案1】:

您可以尝试拆分“:”上的字符串,然后使用 int("2") 将数字转换为 int。

然后可以将结果放入字典中:

d = {}
d['John'] = 6

如果您已经有一个项目 (if x in d:),您可以比较旧值和新值。

【讨论】:

  • 永远不要使用has_key; Python dicts 支持基于语法的成员资格检查,并且 has_key 一直被弃用(它在 Python 3 中消失了)。 if d.has_key(x): 可以规范地(并且更有效地引导)表示为 if x in d:
  • 首先,我要感谢您 - 正是我正在寻找的那种答案和指导,并且提供的指导使我了解从哪里接近,我一定会去练习字典。
  • 我现在唯一失去的是将整数与字符串分开,以及即使在整数与字符串分开之后,我如何将名称和整数添加到字典中,如果那样的话有道理..
  • 在你学习的过程中,我会推荐你​​去谷歌。例如:从我的回答中,您可以 Ctrl+c Ctrl-v “拆分字符串”并在末尾添加“python”,谷歌会告诉您答案。
  • 我当然会这样做,只是我很难理解如何获取代码以将列表中的每个项目添加到字典中,并将两位分开..它将如何知道初始分离后哪个人的分数是多少?
【解决方案2】:

将您的列表转换为元组,然后很容易排序 sorting

from operator import itemgetter

st = [('John',6), ('Bob',9), ('Billy', 8), ('Matthew',7),
      ('Jimmy',2), ('Amy', 9), ('Jenny',10),('Michael',8)]


print(sorted(st, key=itemgetter(1),reverse=True))

[('Jenny', 10), ('Bob', 9), ('Amy', 9), ('Billy', 8), ('Michael', 8), ('Matthew', 7), ('John', 6), ('Jimmy', 2)]

【讨论】:

  • 这似乎是一种高效的方法,您能否向我解释一下这段代码是如何工作的,或者可以指出我可能会阅读它以更好地理解您所写的内容?
  • 另外,我该如何转换列表?
【解决方案3】:

键/值字符串列表不是解决您的问题的合适数据结构,因为它需要字符串操作来提取值。您可能应该将数据解析为 Dictionary 或元组列表。

使用字典

d = {'John': 6, 'Bob': 9, 'Billy': 2, 
     'Matthew': 7, 'Jimmy': 2, 'Amy': 9, 
     'Jenny': 10, 'Michael': 8}

你可以这样做

# highest score
hs_name = max(d, key=d.get) 
hs = d.get(hs_name)

output = "The winner is {} ({} Points)".format(hs_name, hs)
print(output)

字典在内存中没有顺序,但您可以得到它们的排序表示:

# print ordered
import operator
sorted_d = sorted(d.items(), key=operator.itemgetter(1))

print(sorted_d)

如果你想以有序的方式将字典存储在内存中,你可以考虑使用OrderedDict

您还可以考虑使用键/值对列表作为数据结构:

使用元组列表

lt = [('John', 6), ('Bob', 9), ('Billy', 2), 
      ('Matthew', 7), ('Jimmy', 2), ('Amy', 9), 
      ('Jenny', 10), ('Michael', 8)]

# print ordered
sorted_lt = sorted(lt, key=lambda x: x[1], reverse=True)
print(sorted_lt)

# highest score
hs_name = sorted_lt[0][0]
hs = sorted_lt[0][1]

output = "The winner is {} ({} Points)".format(hs_name, hs)
print(output)

我不知道你的具体要求是什么,以及你想要按什么平均数排序(毕竟每个学生只有一个值),但这应该会给你一个想法。

【讨论】:

  • 我一定会对此进行调查,看看我的想法,非常感谢您的回答。
【解决方案4】:

这可能不是最pythonic的方式(我在代码中留下了cmets,希望你能理解,如果不只是问的话):

#Your input list (changed so you can check your requirements when there's two scores for the same person)
input_list = ['John : 6', 'Bob : 10', 'Bob : 9', 'Billy : 2', 'Matthew : 7', 'Jimmy : 2', 'Amy: 9', 'Jenny : 10', 'Michael : 8']

#Transform into a List of tuples
scores = [(item.split(":")[0].strip(), item.split(":")[1].strip()) for item in input_list]

"""CASE 1 - Order alphabetically, and if there is 2 entries for the same person it should only print the highest of the entries for that student"""

print("Entering Case 1")

#create a dictionary with names and delete duplicates (save only the highest score for a given student)
dictionary_by_names = dict()

for item in scores:
    if item[0] not in dictionary_by_names:
        dictionary_by_names[item[0]] = item[1]
    else:
        dictionary_by_names[item[0]] = max(int(item[1]), int(dictionary_by_names[item[0]]))

#order by name (List of tuples)
list_by_names = sorted([(key,value) for key, value in dictionary_by_names.items()])

print(list_by_names)

"""CASE 2 - Order by score, taking their highest and ignoring other entries"""
print("Entering Case 2")

#invert dictionary_by_names, since we only want the highest score of a given duplicate
dictionary_by_scores = [(int(value), key) for key, value in dictionary_by_names.items()]

#Sort the list formed from the dictionary (cast the score to int so we can perform sort of int instead of string, because '10' < '2'  (strings) and 10 > 2 (int))
list_by_score = sorted([(key,value) for key, value in dictionary_by_scores])
#Cast to string again so we can have it in the "original format"
list_by_score = [(str(item[0]), item[1]) for item in list_by_score]
#Invert tuples order so we can have it in the "original format"
list_by_score = [(item[1], item[0]) for item in list_by_score]

print(list_by_score)


"""CASE 3 - If more than one entry for the same student, calculate the average of their scores, and then order the average of each student high to low"""
print("Entering Case 3")

#create a dictionary with names and averages for students
dictionary_by_avg = dict()

for item in scores:
    if item[0] not in dictionary_by_avg:
        dictionary_by_avg[item[0]] = float(item[1])
    else:
        dictionary_by_avg[item[0]] = sum([float(item[1]), float(dictionary_by_avg[item[0]])])/2

list_by_avg = sorted([(value,key) for key, value in dictionary_by_avg.items()])
#Invert tuples order so we can have it in the "original format"
list_by_avg = [(item[1], item[0]) for item in list_by_avg]

print(list_by_avg)

输出:

Entering Case 1
[('Amy', '9'), ('Billy', '2'), ('Bob', 10), ('Jenny', '10'), ('Jimmy', '2'), ('John', '6'), ('Matthew', '7'), ('Michael', '8')]
Entering Case 2
[('Billy', '2'), ('Jimmy', '2'), ('John', '6'), ('Matthew', '7'), ('Michael', '8'), ('Amy', '9'), ('Bob', '10'), ('Jenny', '10')]
Entering Case 3
[('Billy', 2.0), ('Jimmy', 2.0), ('John', 6.0), ('Matthew', 7.0), ('Michael', 8.0), ('Amy', 9.0), ('Bob', 9.5), ('Jenny', 10.0)]

希望这是您想要实现的目标,下次细分您的问题并发布您尝试过的代码块我承认这个问题不是线性的,但您可以完成其中的一部分。

希望这会有所帮助。

顺便说一句,检查一些对您有帮助的文档:

Data Structures

Control Flow Tools

我敢打赌,如果您阅读过它,您本可以构建自己的解决方案。 :)

【讨论】:

  • 这正是我想要实现的目标。我无法表达足够的感谢,尽管我自己写它会受益匪浅。非常感谢。
  • 唯一的问题是,在案例 2 和 3 中,我如何将分数从高到低而不是从低到高排序?
  • 好吧,我会让你发现:) 我认为这是一个很好的练习,可以让你理解这段代码并改变它。如果你有什么不明白的,请尽管问。 =)
  • 好的,我完全明白!我很想自己写,所以我可能会使用你的代码作为基础重写,我非常感谢你的帮助和时间——这对像我这样的初学者来说非常有价值。
  • 在你反转元组之前,我使用 .reverse() 创建了一个新值,然后它成功运行,非常感谢!
【解决方案5】:

我建议使用字典而不是您的列表。字典通过配对键和值来工作。例如:

d = {}
d = {'key':'value'}

要转换您的列表,您可以使用: 作为拆分点拆分键和值的字符串。例如:

test = ('John : 2')
print (test.split(" : "))

返回:

['John', '2']

总而言之,这里有一个代码示例,将您的列表拉入并将其转换为字典,然后按名称排序:

import operator

data = ['John : 6', 'Bob : 9', 'Billy : 2', 'Matthew : 7', 'Jimmy : 2', 'Amy : 9', 'Jenny : 10', 'Michael : 8']

new_data = {}
for i in range(len(data)):
    split_data = data[i].split(" : ")
    new_data[split_data[0]] = split_data[1]

new_data = sorted(new_data.items(), key=operator.itemgetter(0))
print (new_data)

【讨论】:

  • 那么..我如何让它拆分列表中的所有项目,将它们全部转换并附加到一个字典?..好像我问的太多了,但一个例子会很重要如果可能的话,感激不尽
  • 忘记了按名称排序...补充说。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-03
  • 2015-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-27
相关资源
最近更新 更多