在 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']
对于这个问题,将事物随机化听起来不是个好主意。
因为
- 随机可以复制已经存在的ID。
- 您需要跟踪已提供的 ID,以确保您没有重新生成相同的 ID。
我们应该看看这类问题的真实例子。真实例子有规则可确保
- ID不费吹灰之力
- 易于生成。
我住在土耳其,土耳其身份证号码有一些(我知道的)规则:
- 所有数字都应为 11 位数字。
- 所有身份证号码必须是偶数。以偶数结尾。
- 最后一位必须等于前 10 位除以 10 的提示。
在我工作的大学里,每个学生都有一个编号。规则:
- 这个数字的前两位数字是学生入学的年份。 (2021 年为 21 个)
- 接下来的 3 个数字是该学生所属 faculty/institute 的标识符。
- 3号是部门
- 提示号码是学生被院系录取的顺序。
现在回答你的问题。您显示的图像只是给定列表(字母表)的排列。
为此你应该明白排列的数量增长得很快。 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]
注意:使用此代码
- 我们没有检查给定的
start_from
是否仅包含来自 list_of_elements
的元素
- 如果我们尝试从最后一个可能的排列继续,我们将转到第一个排列。
这些问题就交给你了
现在我们可以使用 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
这是我尝试过的,但它输出了不同的字符串
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']
对于这个问题,将事物随机化听起来不是个好主意。
因为
- 随机可以复制已经存在的ID。
- 您需要跟踪已提供的 ID,以确保您没有重新生成相同的 ID。
我们应该看看这类问题的真实例子。真实例子有规则可确保
- ID不费吹灰之力
- 易于生成。
我住在土耳其,土耳其身份证号码有一些(我知道的)规则:
- 所有数字都应为 11 位数字。
- 所有身份证号码必须是偶数。以偶数结尾。
- 最后一位必须等于前 10 位除以 10 的提示。
在我工作的大学里,每个学生都有一个编号。规则:
- 这个数字的前两位数字是学生入学的年份。 (2021 年为 21 个)
- 接下来的 3 个数字是该学生所属 faculty/institute 的标识符。
- 3号是部门
- 提示号码是学生被院系录取的顺序。
现在回答你的问题。您显示的图像只是给定列表(字母表)的排列。
为此你应该明白排列的数量增长得很快。 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]
注意:使用此代码
- 我们没有检查给定的
start_from
是否仅包含来自list_of_elements
的元素
- 如果我们尝试从最后一个可能的排列继续,我们将转到第一个排列。
这些问题就交给你了
现在我们可以使用 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