在 python 中创建非常相似的字符串(只有一位不同)

create strings that are very similar (only differ in one bit) in python

这是我尝试过的,但它输出了不同的字符串

import string
import random
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
   return ''.join(random.choice("abcdefghijklmnopqrstuvwxyz") for _ in range(5))
print(id_generator())

这似乎是一项家庭作业,所以我会给你一些伪代码来处理。

# Create a list of all the ascii lowercase characters.

# Get a random letter from list of ascii lowercase letters.
# Make sure it isn't the first letter. 

# Replace the first letter in the list of all ascii lowercase letters
# with the random letter.

# Create a str from the list of all the ascii lowercase letters

对于您的特定示例,您可以使用 itertools.product:

from string import ascii_lowercase
from itertools import product

list(map(''.join, product(ascii_lowercase, [ascii_lowercase[1:]])))

输出:

['abcdefghijklmnopqrstuvwxyz',
 'bbcdefghijklmnopqrstuvwxyz',
 'cbcdefghijklmnopqrstuvwxyz',
 'dbcdefghijklmnopqrstuvwxyz',
 'ebcdefghijklmnopqrstuvwxyz',
 'fbcdefghijklmnopqrstuvwxyz',
 'gbcdefghijklmnopqrstuvwxyz',
 'hbcdefghijklmnopqrstuvwxyz',
 'ibcdefghijklmnopqrstuvwxyz',
 'jbcdefghijklmnopqrstuvwxyz',
 'kbcdefghijklmnopqrstuvwxyz',
 'lbcdefghijklmnopqrstuvwxyz',
 'mbcdefghijklmnopqrstuvwxyz',
 'nbcdefghijklmnopqrstuvwxyz',
 'obcdefghijklmnopqrstuvwxyz',
 'pbcdefghijklmnopqrstuvwxyz',
 'qbcdefghijklmnopqrstuvwxyz',
 'rbcdefghijklmnopqrstuvwxyz',
 'sbcdefghijklmnopqrstuvwxyz',
 'tbcdefghijklmnopqrstuvwxyz',
 'ubcdefghijklmnopqrstuvwxyz',
 'vbcdefghijklmnopqrstuvwxyz',
 'wbcdefghijklmnopqrstuvwxyz',
 'xbcdefghijklmnopqrstuvwxyz',
 'ybcdefghijklmnopqrstuvwxyz',
 'zbcdefghijklmnopqrstuvwxyz']

对于这个问题,将事物随机化听起来不是个好主意。

因为

  1. 随机可以复制已经存在的ID。
  2. 您需要跟踪已提供的 ID,以确保您没有重新生成相同的 ID。

我们应该看看这类问题的真实例子。真实例子有规则可确保

  1. ID不费吹灰之力
  2. 易于生成。

我住在土耳其,土耳其身份证号码有一些(我知道的)规则:

  1. 所有数字都应为 11 位数字。
  2. 所有身份证号码必须是偶数。以偶数结尾。
  3. 最后一位必须等于前 10 位除以 10 的提示。

在我工作的大学里,每个学生都有一个编号。规则:

  1. 这个数字的前两位数字是学生入学的年份。 (2021 年为 21 个)
  2. 接下来的 3 个数字是该学生所属 faculty/institute 的标识符。
  3. 3号是部门
  4. 提示号码是学生被院系录取的顺序。

现在回答你的问题。您显示的图像只是给定列表(字母表)的排列。

为此你应该明白排列的数量增长得很快。 n!/(n-r)!

其中 n 是元素的数量(在您的示例中是字母表),r 是字符串的长度(在您的示例中是 ID)。

这里 Python 的发电机来救援。

我们需要一个函数来生成排列。如果它给出一个状态,它应该从那里开始:

def nex_permutation(list_of_elements, r, start_from):
    res = ""
    if len(start_from) != r:
        raise ValueError(f"start_from length and r are not equal")

    carry = 1
    for i in start_from[::-1]:
        ind = list_of_elements.index(i) + carry
        carry = ind // len(list_of_elements)
        res += list_of_elements[ind % len(list_of_elements)]

    return res[::-1]

注意:使用此代码

  1. 我们没有检查给定的 start_from 是否仅包含来自 list_of_elements
  2. 的元素
  3. 如果我们尝试从最后一个可能的排列继续,我们将转到第一个排列。

这些问题就交给你了

现在我们可以使用 nex_permutation 生成下一个函数。这里我们将使用 yield 而不是 return。因此这个函数变成了一个生成器。使用生成器,您可以根据需要计算下一个元素。

def permuataion(list_of_elements, r, start_from=None):
    if start_from is None:
        start_from = list_of_elements[0] * r
        yield start_from
    while True:
        start_from = nex_permutation(list_of_elements, r, start_from=start_from)
        yield start_from

现在开始使用它:

a = permuataion("abcd", 4)

for _ in range(3):
    print(next(a))

输出:

aaaa
aaab
aaac

测试是否继续:

a = permuataion("abcd", 4, start_from="aabd")

for _ in range(3):
    print(next(a))

输出:

aaca
aacb
aacc