首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按字母顺序返回字符串中的字符

按字母顺序返回字符串中的字符
EN

Code Review用户
提问于 2017-08-23 02:23:23
回答 3查看 8.8K关注 0票数 12

问题

  • 取一个字符串并按字母顺序返回所有输入字符。
  • 假设不使用数字或标点符号。
  • 对于同一字符,大写字符应在小写字符之前返回。
  • 不要使用sorted助手方法
  • 不要使用Python 3.6.1中没有包含的任何库

例如,alphabetize(HelLo)应该返回eHLlo

逼近

  1. 创建一个26元素列表。此列表将表示通过字典查看的不同字母字符的计数(大写和小写)。
  2. 迭代输入字符串中的字符
    1. 通过从intint值中减去小写字符的a值来获取每个字符的索引
    2. 从计数字典中获取该索引的现有计数&大小写
    3. 1增加计数

  3. 初始化返回字符串
  4. 迭代列表中的每个元素
    1. 对于每个字典/元素,获取字符,并获得大写和小写计数。
    2. 将大写字符添加到返回字符串中
    3. 将小写字符添加到返回字符串中

  5. 返回按字母排序的字符串

实现讨论

我知道实现这一目标的'Pythonic‘方式类似于''.join(sorted(myString))

然而,作为一个试图学习Python的人,我想用这个练习来更多地了解Python中的字符串和字符(例如),而不是在Googling上搜索一行(并不是说这有什么问题)。

我关心的事情:

  • 这应该是一堂课吗?还是可以作为一种独立的方法?(作为一个更熟悉Java的人,课堂上没有的东西会让我不理性地感到不安。)
  • 说到这一点,这种方法中有相当多的东西在进行,我应该把它分开吗?
    • 如果我决定将其分解,有什么正确的方法来“显示”某些函数只供另一个函数使用?
    • 我认为Python并没有真正的privatepublic的概念,所以我在这里_(some_method_name)吗?

  • 除了使用sorted方法之外,我还遗漏了哪些“Pythonic”元素?

Implementation

代码语言:javascript
复制
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
EN

回答 3

Code Review用户

回答已采纳

发布于 2017-08-23 03:55:04

除了使用排序方法之外,我还遗漏了哪些“Pythonic”元素?

如果希望更多地使用标准库,可以使用collections.Counter以及字母表常数 string.ascii_uppercasestring.ascii_lowercase

如果将计数存储在dict (map)中而不是当前使用的隐式map byord()-value中,则情况也更简单。计数的顺序并不重要,而是输出它们的顺序。

代码语言:javascript
复制
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)行本质上是这样做的:

代码语言:javascript
复制
counts = collections.defaultdict(int)

for char in s:
    counts[char] += 1

其中,defaultdict (一个方便的类)是一个基于您传入的构造函数自动初始化值的dict,而不是为缺少的键抛出异常。

chain(*zip(...))将大写字母和小写字母拉链在一起,然后通过chain()将它们压缩到一个列表['A', 'a', 'B', ...]中。

这应该是一堂课吗?

不是的。这在Python中是有意义的,因为它没有外部状态。

作为一个更熟悉Java的人,课堂上没有的东西会让我不理性地感到不安。

Java将文件绑定到类,但每个Python文件都已经是一个模块,这是一个很好的封装级别。作为一条非常粗略的规则,避免使用Python中的类,除非您想要保持共享状态,在这种情况下,类会消失。或者,至少,不要先去上课。

票数 10
EN

Code Review用户

发布于 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
票数 5
EN

Code Review用户

发布于 2017-08-24 10:05:37

编辑;免责声明:我实际上把“按字母顺序返回所有输入字符”这句话理解为一组问题,因此我的答案将只返回输入字符串中每种类型的一个字符。

我保留了它的原样,因为它可以回答一些用例。

我的第一个步骤如下,但只有当所有字符都在字符串中时,才能工作,否则结果会很奇怪:

代码语言:javascript
复制
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顺序返回字符,因此

代码语言:javascript
复制
l = [a for tuple in zip(string.ascii_uppercase, string.ascii_lowercase) for a in tuple]

按正确的顺序返回列表,

代码语言:javascript
复制
s = {a for tuple in zip(string.ascii_uppercase, string.ascii_lowercase) for a in tuple}

按字母顺序返回大写,然后按字母顺序返回小数。

所以我只分别对每个集合做子运算(我从输入中移除引用集和集合之间的区别,这基本上只留下输入中的集合,但这一次对每一类字符(大写/小写)进行排序,并将它们连接到zip中,然后切换到保持输入顺序的列表中。

我的第二个选择是根据相同的原则进行变体,只使用一组引用:导入字符串。

代码语言:javascript
复制
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

我的第三种选择对每一种情况都更有效:

代码语言:javascript
复制
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,这更适合我的心态来解决这样的问题。

希望能帮上忙。

我想给它计时,但我不能,我正在打电话。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/173719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档