sorted助手方法例如,alphabetize(HelLo)应该返回eHLlo
int的int值中减去小写字符的a值来获取每个字符的索引1增加计数我知道实现这一目标的'Pythonic‘方式类似于''.join(sorted(myString))。
然而,作为一个试图学习Python的人,我想用这个练习来更多地了解Python中的字符串和字符(例如),而不是在Googling上搜索一行(并不是说这有什么问题)。
我关心的事情:
private和public的概念,所以我在这里_(some_method_name)吗?sorted方法之外,我还遗漏了哪些“Pythonic”元素?def alphabetize(value):
uppercase_key = 'uppercase'
lowercase_key = 'lowercase'
character_counts = []
for i in range(26):
character_counts.append({uppercase_key: 0, lowercase_key: 0}.copy())
for character in value:
index = ord(character.lower()) - ord('a')
counts = character_counts[index]
key = uppercase_key if character.isupper() else lowercase_key
count = counts[key]
counts[key] = count + 1
alphabetized = ''
for index, counts in enumerate(character_counts):
character = chr(ord('a') + index)
uppercase_counts = counts[uppercase_key]
lowercase_counts = counts[lowercase_key]
for i in range(uppercase_counts):
alphabetized += character.upper()
for i in range(lowercase_counts):
alphabetized += character
return alphabetized发布于 2017-08-23 03:55:04
除了使用排序方法之外,我还遗漏了哪些“Pythonic”元素?
如果希望更多地使用标准库,可以使用collections.Counter以及字母表常数 string.ascii_uppercase和string.ascii_lowercase。
如果将计数存储在dict (map)中而不是当前使用的隐式map byord()-value中,则情况也更简单。计数的顺序并不重要,而是输出它们的顺序。
from collections import Counter
from itertools import chain
import string
def alphabetize(s):
counts = Counter(s)
return ''.join(
char * counts[char]
for char in chain(*zip(string.ascii_uppercase, string.ascii_lowercase))
)counts = Counter(s)行本质上是这样做的:
counts = collections.defaultdict(int)
for char in s:
counts[char] += 1其中,defaultdict (一个方便的类)是一个基于您传入的构造函数自动初始化值的dict,而不是为缺少的键抛出异常。
chain(*zip(...))将大写字母和小写字母拉链在一起,然后通过chain()将它们压缩到一个列表['A', 'a', 'B', ...]中。
这应该是一堂课吗?
不是的。这在Python中是有意义的,因为它没有外部状态。
作为一个更熟悉Java的人,课堂上没有的东西会让我不理性地感到不安。
Java将文件绑定到类,但每个Python文件都已经是一个模块,这是一个很好的封装级别。作为一条非常粗略的规则,避免使用Python中的类,除非您想要保持共享状态,在这种情况下,类会消失。或者,至少,不要先去上课。
发布于 2017-08-23 03:01:00
copy()调用{uppercase_key: 0, lowercase_key: 0}.copy()是多余的。如果您将这个数据块分配给某个变量并附加该变量,copy()就会有意义。+=来创建大字符串,它可能导致二次time.The推荐的方法是创建这样的字符串列表,然后使用str.join连接它们。检查:性能提示:字符串连接。count = counts[key]; counts[key] = count + 1基本上是counts[key] += 1。发布于 2017-08-24 10:05:37
编辑;免责声明:我实际上把“按字母顺序返回所有输入字符”这句话理解为一组问题,因此我的答案将只返回输入字符串中每种类型的一个字符。
我保留了它的原样,因为它可以回答一些用例。
我的第一个步骤如下,但只有当所有字符都在字符串中时,才能工作,否则结果会很奇怪:
import string
def alphabetize(inputstr):
inputset = set(inputstr)
refset_caps = set (string.ascii_uppercase)
refset_mins = set (string.ascii_lowercase)
leftcaps = refset_caps -(refset_caps - inputset)
leftmins = refset_mins -(refset_mins - inputset)
finalstr = list(zip(leftcaps , leftmins))
#finalstr = str(l).strip("[']").replace("', '","")
#Line above should be used in case you need to return a string and not a list, you can adapt the replace input to keep commas, too.
return finalstr说明1:一开始我只想做一组,但这忘记了集合本身并不是有序的。另一方面,它们具有一个很好的属性,可以按unicode顺序返回字符,因此
l = [a for tuple in zip(string.ascii_uppercase, string.ascii_lowercase) for a in tuple]按正确的顺序返回列表,
s = {a for tuple in zip(string.ascii_uppercase, string.ascii_lowercase) for a in tuple}按字母顺序返回大写,然后按字母顺序返回小数。
所以我只分别对每个集合做子运算(我从输入中移除引用集和集合之间的区别,这基本上只留下输入中的集合,但这一次对每一类字符(大写/小写)进行排序,并将它们连接到zip中,然后切换到保持输入顺序的列表中。
我的第二个选择是根据相同的原则进行变体,只使用一组引用:导入字符串。
def alphabetize(inputstr):
inputset = set(inputstr)
prestr = [chrt for sublist in zip(string.ascii_uppercase , string.ascii_lowercase) for chrt in sublist]
refset = set(prestr)
leftchars = refset -(refset - inputset)
finalstr = [character for character in inputset if character in leftchars ]
#I could also have written directly finalstr = [character for character in inputset if character not in (refset - inputset)]
#finalstr = str(prestr2 ).strip("[']").replace("', '","")
#Line above should be used in case you need to return a string and not a list, you can adapt the replace input to keep commas, too.
return finalstr我的第三种选择对每一种情况都更有效:
import string
def alphabetize(inputstr):
inputset = set(inputstr)
prestr = [chrt for sublist in zip(string.ascii_uppercase , string.ascii_lowercase) for chrt in sublist]
refset = set(prestr)
for character in (refset - inputset):
prestr.remove(character )
"""but I guess it adds loads of complexity to the operation, as removing depends on length of the list -while here it is and always be limited- and is slower by conception than set operation"""
finalstr = prestr.copy() #or
#finalstr = str(prestr2 ).strip("[']").replace("', '","")
#Line above should be used in case you need to return a string and not a list, you can adapt the replace input to keep commas, too.
return finalstr无论如何,与计数器相比,我更喜欢这种方式,而且本质上它也避免使用大多数导入(您甚至可以通过输入list off来避免导入字符串模块)。我认为,通过使用这些操作的集合,封装列表的理解,这是相当有神的。
我不知道这是否是性能的改善,但我认为打火机更好,所以少进口更好。此外,使用计数器是一种复杂的方法来完成Python中已经存在的事情--使用集合作为排序的替代方法。
否则,我不能提供比个人品味更多的理由,但在类似的表现上,我更喜欢使用set,这更适合我的心态来解决这样的问题。
希望能帮上忙。
我想给它计时,但我不能,我正在打电话。
https://codereview.stackexchange.com/questions/173719
复制相似问题