【问题标题】:how to replace the alphabetically smallest letter by 1, the next smallest by 2 but do not discard multiple occurrences of a letter?如何将按字母顺序最小的字母替换为 1,将下一个最小的字母替换为 2,但不丢弃多次出现的字母?
【发布时间】:2014-09-10 18:47:47
【问题描述】:

我正在使用 Python 3,我想编写一个函数,该函数接受一个全大写字母的字符串,所以假设 s = 'VENEER',并给我以下输出 '614235'

我目前的功能是:

def key2(s):
    new=''
    for ch in s:
        acc=0
        for temp in s:
            if temp<=ch:
                acc+=1
        new+=str(acc)
    return(new)

如果s == 'VENEER'new == '634335'。如果s 不包含重复项,则代码可以完美运行。

我被困在如何编辑代码以获得开头所述的输出。

【问题讨论】:

  • 您的用例没有多大意义。我不明白标题如何与您的示例输入/输出相匹配。

标签: python


【解决方案1】:

您可以使用正则表达式:

import re

s="VENEER"
for n, c in enumerate(sorted(s), 1):
    s=re.sub('%c' % c, '%i' % n, s, count=1)

print s
# 614235

您还可以使用多个嵌套生成器:

def indexes(seq):
    for v, i in sorted((v, i) for (i, v) in enumerate(seq)):
        yield i

print ''.join('%i' % (e+1) for e in indexes(indexes(s)))
# 614235

【讨论】:

  • 我认为预期的输出是'614235'
【解决方案2】:

根据你的标题,你可能想这样做?

>>> from collections import OrderedDict
>>> s='VENEER'
>>> d = {k: n for n, k in enumerate(OrderedDict.fromkeys(sorted(s)), 1)}
>>> "".join(map(lambda k: str(d[k]), s))
'412113'

正如@jonrsharpe 所说,我不需要使用OrderedDict

【讨论】:

  • 你通过OrderedDict做的事情可以简化为sorted(set(s));集合实际上是一个没有值的字典,并且不能有重复项。
  • @jonrsharpe:set 不在乎列表顺序。所以我需要使用OrderdDict。但是sorted(set(s)),我只是没有注意到...谢谢。 :)
【解决方案3】:

请注意,用于替换字符串中字符的内置方法str.replace 采用第三个参数; count。您可以利用这一点,只替换每个字母的第一次出现(显然,一旦您替换了第一个 'E',第二个将成为第一个出现,依此类推):

def process(s):
    for i, c in enumerate(sorted(s), 1):
##        print s # uncomment to see process
        s = s.replace(c, str(i), 1)
    return s

我已经使用了内置函数sortedenumerate来获取合适的数字来替换字符:

1 2 3 4 5 6 # 'enumerate' from 1 -> 'i'
E E E N R V # 'sorted' input 's' -> 'c'

示例用法:

>>> process("VENEER")
'614235'

【讨论】:

  • 天哪,这比我的回答好太多了。
  • @JonClements 我认为这是key2 目前给 OP 的错误答案。如果这是正确的答案,他们就完成了!
【解决方案4】:
def caps_to_nums(in_string):
    indexed_replaced_string = [(idx, val) for val, (idx, ch) in enumerate(sorted(enumerate(in_string), key=lambda x: x[1]), 1)]
    return ''.join(map(lambda x: str(x[1]), sorted(indexed_replaced_string)))

首先我们运行enumerate 来保存自然排序顺序

enumerate("VENEER") -> [(0, 'V'), (1, 'E'), (2, 'N'), (3, 'E'), (4, 'E'), (5, 'R')]
# this gives us somewhere to RETURN to later.

然后我们根据它的第二个元素(按字母顺序)对其进行排序,并以1 的起始值再次运行enumerate 以获得替换值。我们丢弃了 alpha 值,因为它不再需要了。

[(idx, val) for val, (idx, ch) in enumerate(sorted([(0, 'V'), (1, 'E'), ...], key = lambda x: x[1]), start=1)]
# [(1, 1), (3, 2), (4, 3), (2, 4), (5, 5), (0, 6)]

然后映射第二个元素(我们的值)按第一个元素(原始索引)排序

map(lambda x: str(x[1]), sorted(replacement_values)

str.join

''.join(that_mapping)

哒哒!

【讨论】:

    【解决方案5】:

    一种方法是使用numpy.argsort 查找订单,然后查找排名并加入他们:

    >>> s = 'VENEER'
    >>> order = np.argsort(list(s))
    >>> rank = np.argsort(order) + 1
    >>> ''.join(map(str, rank))
    '614235'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-09
      • 2013-02-04
      • 1970-01-01
      • 2014-06-13
      • 2017-09-24
      • 2015-07-28
      • 1970-01-01
      相关资源
      最近更新 更多