当前位置:  开发笔记 > 编程语言 > 正文

你会如何将这个从Perl翻译成Python?

如何解决《你会如何将这个从Perl翻译成Python?》经验,为你挑选了2个好方法。

我有一个Perl函数,它接受一个时间戳并返回未更改的时间戳(如果之前从未见过它)或者其他,它会附加一些字母以使其唯一:

sub uniqify($) {
  my $timestamp = shift;

  state $last_ts = -1;
  state $next_letter = 'A';

  if ($timestamp == $last_ts) {
    $timestamp .= $next_letter++;
  } else {
    $last_ts = $timestamp;
    $next_letter = 'A';
  }

  return $timestamp;
}

因此,如果您使用值1,1,1和2调用它四次,它将返回1,然后是1A,然后是1B,然后是2.

注意:它只会被不断增加的时间戳调用,所以它不需要回忆它所见过的每一个,只是最后一个.

现在我需要将此函数转换为Python.我已经知道我可以用globals替换"state"变量(yuck!)或者可能将它们作为属性附加到函数中,但这些都不是特别优雅.

此外,Python没有类似Perl的魔法自动增量,如果你"++"是一个值为"A"的变量,它变为"B" - 或者如果它是"Z",它就变成"AA".所以这也是一个曲线球.

我是一个黑客攻击解决方案,但它真的很丑,难以阅读.从Perl到Python的翻译应该会产生相反的效果,对吧?:)所以我将此作为对SO用户的挑战.你能把它变成一个优雅的Python函数吗?



1> hasen..:

请查看此答案,了解将数字转换为字母数字ID的强大方法

我提供的代码不是从'Z'变为'AA',而是变为'BA',但我认为这无关紧要,它仍会产生一个唯一的id

from string import uppercase as up
import itertools

def to_base(q, alphabet):
    if q < 0: raise ValueError( "must supply a positive integer" )
    l = len(alphabet)
    converted = []
    while q != 0:
        q, r = divmod(q, l)
        converted.insert(0, alphabet[r])
    return "".join(converted) or alphabet[0]

class TimestampUniqifier( object ):
    def __init__(self):
        self.last = ''
        self.counter = itertools.count()
    def __call__( self, str ):
        if str == self.last:
            suf = self.counter.next()
            return str + to_base( suf, up )
        else:
            self.last = str
            self.counter = itertools.count()
            return str            

timestamp_uniqify = TimestampUniqifier()

用法:

timestamp_uniqify('1')
'1'
timestamp_uniqify('1')
'1A'
timestamp_uniqify('1')
'1B'
timestamp_uniqify('1')
'1C'
timestamp_uniqify('2')
'2'
timestamp_uniqify('3')
'3'
timestamp_uniqify('3')
'3A'
timestamp_uniqify('3')
'3B'

你可以称之为maaaany次,它仍然会产生良好的效果:

for i in range(100): print timestamp_uniqify('4')

4
4A
4B
4C
4D
4E
4F
4G
4H
4I
4J
4K
4L
4M
4N
4O
4P
4Q
4R
4S
4T
4U
4V
4W
4X
4Y
4Z
4BA
4BB
4BC
4BD
4BE
4BF
4BG
4BH
4BI
4BJ
4BK
4BL
4BM
4BN
4BO
4BP
4BQ
4BR
4BS
4BT
4BU
4BV
4BW
4BX
4BY
4BZ
4CA
4CB
4CC
4CD
4CE
4CF
4CG
4CH
4CI
4CJ
4CK
4CL
4CM
4CN
4CO
4CP
4CQ
4CR
4CS
4CT
4CU
4CV
4CW
4CX
4CY
4CZ
4DA
4DB
4DC
4DD
4DE
4DF
4DG
4DH
4DI
4DJ
4DK
4DL
4DM
4DN
4DO
4DP
4DQ
4DR
4DS
4DT
4DU



2> Ali Afshar..:

好吧,很遗憾地说,但你不能只是直接从Perl转换到Python(包括逐位Perlisms)并期望结果更漂亮.它不会,它会更加丑陋.

如果你想要Python的美味,你需要使用Python习语.

现在提出问题:

from string import uppercase

class Uniquifier(object):

    def __init__(self):
        self.last_timestamp = None
        self.last_suffix = 0

    def uniquify(self, timestamp):
        if timestamp == self.last_timestamp:
            timestamp = '%s%s' % (timestamp,
                                  uppercase[self.last_suffix])
            self.last_suffix += 1
        else:
            self.last_suffix = 0
            self.timestamp = timestamp
        return timestamp

uniquifier = Uniquifier()
uniquifier.uniquify(a_timestamp)

更漂亮?也许.更具可读性?大概.

编辑(重新评论):是的,这在Z之后失败了,我对这个解决方案完全不满意.所以我不会解决它,但可能提供更好的东西,比如使用数字:

timestamp = '%s%s' % (timestamp,
                      self.last_suffix)

如果是我,我会这样做:

import uuid

def uniquify(timestamp):
    return '%s-%s' % (timestamp, uuid.uuid4())

只是快乐.

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有