简体   繁体   English

具有 0-9 和 AZ 的 Python 序列号生成器

[英]Python sequential number generator with 0-9 and A-Z

I'm trying to accomplish a number generator which increments numbers (0-9) and characters (AZ not case-sensitive) for unique identification of some object in our software project.我正在尝试完成一个数字生成器,它递增数字(0-9)和字符(AZ 不区分大小写),以便在我们的软件项目中唯一标识某些对象。 The output string should have a length of 14.输出字符串的长度应为 14。

The generator should be able to create a range of sequential numbers/characters (see examples below) which will be used on potential hundres of devices running some python applications with databases.生成器应该能够创建一系列序列号/字符(参见下面的示例),这些序列号/字符将用于运行一些带有数据库的 python 应用程序的潜在数百台设备。 We would like to implement following logic and 'provide' these sequential number ranges to the devices so we make sure we have unique ids across all systems.我们希望实现以下逻辑并将这些序列号范围“提供”给设备,因此我们确保我们在所有系统中都有唯一的 ID。 We would prefer this logic instead of classic random id creation.我们更喜欢这种逻辑而不是经典的随机 id 创建。

Increment should start from right to left.增量应该从右到左开始。 Numbers start with 0-9.数字以 0-9 开头。 If 9 is reached, the index should then increment from AZ.如果达到 9,则索引应从 AZ 开始递增。 If Z is reached, the left index number should be incremented from 0 to 1 or 9 => AZ(one higher).如果达到 Z,则左侧索引号应从 0 增加到 1 或 9 => AZ(高一)。 The right index should then again be incremented by the same logic starting by 0 => 1-9 and afterwards AZ.然后,正确的索引应该再次以相同的逻辑递增,从 0 => 1-9 开始,然后是 AZ。

A few example outputs:一些示例输出:

  • 00000000000009 00000000000009
  • 0000000000000A 0000000000000A
  • 0000000000000B 0000000000000B

Or:或者:

  • 0000000000000Z 0000000000000Z
  • 00000000000010 00000000000010
  • 00000000000011 00000000000011

And so on.等等。

The function should also be able to start at a given number, for eg 00000000005X which then continues with 00000000005Y etc..该函数还应该能够以给定的数字开始,例如 00000000005X ,然后以 00000000005Y 等继续。

How can I build this in Python?如何在 Python 中构建它?

You can use constants from the string module to get all the digits / uppercase ASCII characters, and then use itertools.product to generate the IDs:您可以使用string模块中的常量来获取所有数字/大写 ASCII 字符,然后使用itertools.product生成 ID:

import string
import itertools

# Create the iterable.
characters = string.digits + string.ascii_uppercase
n = 14
id_iterable = map(''.join, itertools.product(characters, repeat=n))

# Get the first 50 elements in the iterable and print them out (for demo purposes).
head = list(itertools.islice(id_iterable, 50))
print(*head, sep='\n')

This outputs:这输出:

00000000000000
00000000000001
00000000000002
00000000000003
00000000000004
00000000000005
00000000000006
00000000000007
00000000000008
00000000000009
0000000000000A
0000000000000B
0000000000000C
0000000000000D
0000000000000E
0000000000000F
0000000000000G
0000000000000H
0000000000000I
0000000000000J
0000000000000K
0000000000000L
0000000000000M
0000000000000N
0000000000000O
0000000000000P
0000000000000Q
0000000000000R
0000000000000S
0000000000000T
0000000000000U
0000000000000V
0000000000000W
0000000000000X
0000000000000Y
0000000000000Z
00000000000010
00000000000011
00000000000012
00000000000013
00000000000014
00000000000015
00000000000016
00000000000017
00000000000018
00000000000019
0000000000001A
0000000000001B
0000000000001C
0000000000001D

You can try:你可以试试:

import numpy as np

def f(start):
    n = int(start, base=36)
    while True:
        yield np.base_repr(n, 36).rjust(14,"0")
        n += 1

Then:然后:

g = f('0000000000012S')

for i in range(10):
    print(next(g))

It gives:它给:

0000000000012S
0000000000012T
0000000000012U
0000000000012V
0000000000012W
0000000000012X
0000000000012Y
0000000000012Z
00000000000130
00000000000131

This program only uses the string module, and not itertools I also added constants called LENGTH and START which you can change该程序仅使用string模块,而不是itertools我还添加了名为LENGTHSTART的常量,您可以更改它们

Code:代码:

from string import ascii_uppercase

sequence = [str(i) for i in range(10)] + list(ascii_uppercase)

LENGTH = 14
START = '0' * LENGTH

last = list(START)
while last != list('Z' * LENGTH):
    print(''.join(last))
    i = 1
    while last[-i] == 'Z':
        last[-i] = '0'
        i += 1
    last = last[:-i] + [sequence[sequence.index(last[-i]) + 1]] + last[LENGTH-i+1:]

Output:输出:

00000000000000 
00000000000001 
00000000000002 
00000000000003 
00000000000004 
00000000000005 
00000000000006 
00000000000007 
00000000000008 
00000000000009 
0000000000000A 
0000000000000B 
0000000000000C 
0000000000000D 
0000000000000E 
0000000000000F 
0000000000000G 
0000000000000H 
0000000000000I 
0000000000000J 
0000000000000K 
0000000000000L 
0000000000000M 
0000000000000N 
0000000000000O 
0000000000000P 
0000000000000Q 
0000000000000R 
0000000000000S 
0000000000000T 
0000000000000U 
0000000000000V 
0000000000000W 
0000000000000X 
0000000000000Y 
0000000000000Z 
00000000000010 
00000000000011 
00000000000012 
00000000000013 
00000000000014 
00000000000015 
00000000000016 
00000000000017 
00000000000018 
00000000000019 
0000000000001A 
0000000000001B 
0000000000001C 
0000000000001D 
0000000000001E 
0000000000001F 
0000000000001G
...

Was using your question as an exercise to see if I could quickly implement the algorithm in JS, wasn't intending on providing the solution, as I expected this "homework-style" question would get answers pretty quickly.正在使用您的问题作为练习,看看我是否可以在 JS 中快速实现该算法,并不打算提供解决方案,因为我预计这个“家庭作业式”问题会很快得到答案。 @bb1's numpy solution seems quite good, as does the itertools approach (though it's not actually written as a generator function). @bb1 的 numpy 解决方案似乎相当不错,itertools 方法也是如此(尽管它实际上并未编写为生成器函数)。 Though both have library overheads.虽然两者都有图书馆开销。

Was a bit surprised there wasn't a good algorithmic approach, just library answers.有点惊讶没有一个好的算法方法,只有图书馆的答案。 So figured I'd share mine even though it was in the wrong language.所以我想我会分享我的,即使它是用错误的语言。 Adopting this for Python shouldn't be too tricky, outside of maybe converting the JS closure to a generator function in Python.在 Python 中采用这个应该不会太棘手,除了可能将 JS 闭包转换为 Python 中的生成器函数。 As this is written, if we happen to hit "ZZZZZZZZZZZZZZ" the next value generated is "00000000000000" and we restart.如本文所述,如果我们碰巧点击“ZZZZZZZZZZZZZZ”,则生成的下一个值是“00000000000000”,然后我们重新启动。

function GetGenerator(start_val) {
    
    const min_val = "0"
    const id_len = 14;
    
    if (start_val && start_val.length != id_len) 
        throw "Initial value length isn't " + id_len
    
    // A dictionary mapping each character to the next & 'Z' to 'undefined'
    const incrementer = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("")
        .reduce((acc, cur, idx, arr) => (acc[cur] = arr[idx+1], acc), {})
    
    const counter = start_val ? start_val.split("") : Array(id_len).fill(min_val)
    
    function increment() {
        //  Moving backwards through the array  <--
        // ["0", "0", "0", "0", ... , "0", "5", "X" ]
        for(let i = id_len - 1; i >= 0; i--) {
            const next = incrementer[counter[i]]
            if (next) {
                counter[i] = next
                return
            } else {
                counter[i] = min_val
                // No return, it's a carry. Increment the next index.
            }                
        }
    }
    
    return function gen() {
        increment()
        return counter.join("")
    }
}

Used like:像这样使用:

const generator = GetGenerator("0000000000005X")

generator()
>>> "0000000000005Y"
generator()
>>> "0000000000005Z"
generator()
>>> "00000000000060"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python计数0-9然后是az - Python count 0-9 then a-z 如何在 Python 中创建带有英文字母(AZ、az、0-9)的图像? - How to create images with English alphabets (A-Z, a-z, 0-9) in Python? python正则表达式re.search(r“([[az] + [AZ] + [0-9] +)”,密码) - python regular expression re.search(r“([a-z]+[A-Z]+[0-9]+)”, password) 如何在Python中仅用“ AZ”,“ az”,“ 0-9”和“ _”编码UTF-8字符串 - How to encode UTF-8 strings with only “A-Z”,“a-z”,“0-9”, and “_” in Python Python 无重复序列号生成器 - Python Sequential number generator with no repeats Python:在给定单词的每个字母后添加多个随机字母(AZ;az)? - Python: add a number of random letters (A-Z; a-z) after each letter in a given word? 如何从“0-9 AZ”按顺序“自动生成”字符串 - How to “Auto Generate” String in Sequence from “0-9 A-Z” 如何使用 re.sub() 只留下字母 az、AZ、数字 0-9 和空格而不是除数? - How to use re.sub() to leave only letters a-z, A-Z, numbers 0-9 and spaces but not divide numbers? 我如何编写regEx来识别字符串何时除了az 0-9以外的其他内容? - How do I write regEx to recognize when a string has anything but a-z 0-9? 生成两个字符的域名 az 0-9 时使用运算符出现问题 - Trouble using operator while generating two character domain names a-z 0-9
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM