python-3.x 有没有可能自定义随机功能,以避免过多的重复单词?[重复]

qaxu7uf2  于 2023-04-08  发布在  Python
关注(0)|答案(5)|浏览(93)

此问题已存在

Customizing the random function without using append, or list, or other container?
4天前关闭。
这篇文章是编辑并提交审查4天前.
从理论上讲,当使用随机化时,同一个单词可能会连续打印几次,也可能会重复打印(例如,5次尝试中有3次可能会打印同一个单词),我知道,这是正确的,这是正确的,正常的。
我想设置一个变量的相同值再次打印ONLY AFTER 4 TIMES,因此在第FIFTH次尝试时。我只是想为每个值设置某种“块”,并且该块必须持续4次打印尝试。
例如,在我的代码中,我想在a_random变量中,如果Word A2被打印,那么Word A2将只能在4次后续打印尝试后再次打印,但我想打印四个中的一个(1)随机单词(而不是打印4个单词)
例如,如果我打印Word A2,随后的打印必须是"Word A1", "Word A3", "Word A4", "Word A5", "Word A6", "Word A7", "Word A8"中的4个随机,那么在第第五次尝试时,他将能够再次打印Word A2(但不是强制性的,因为除了Word A2之外,还可以打印任何单词)

重要提示:我想一次只打印一个单词。我不想一次打印4个单词或更多单词。我希望输出的单词只有一(1)个

谢谢你

import random
import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.geometry('300x200')

def func():
    
   a = "Word A1", "Word A2", "Word A3", "Word A4", "Word A5", "Word A6", "Word A7", "Word A8"
   print("NEW")
   a_random = print(random.choice(a))
   print(" ")  
   return a_random

button = ttk.Button(root, text='Random', command=func)
button.place(x=10, y=10)

root.mainloop()
sulc1iza

sulc1iza1#

这使用一个列表来跟踪黑名单索引并从采样中删除那些索引。该列表不会超过四个项目。

import random
import numpy as np

vocab = np.array([
    "Word A1",
    "Word A2",
    "Word A3",
    "Word A4",
    "Word A5",
    "Word A6",
    "Word A7",
    "Word A8"
])

# a list of all indices of the array
indices = np.arange(0, len(vocab))

# a list that will store blacklisted indices as long as they are forbidden (4 time steps)
blacklist = []

for i in range(10):
    # only allow values that were not used in the last for steps
    random_index = random.choice(list(set(indices) - set(blacklist)))
    # update blacklist for next run
    blacklist = [random_index] + blacklist  # add new index at the beginning
    blacklist = blacklist[0:4]  # only keep four values, remove older items
    print(vocab[random_index])
5fjcxozz

5fjcxozz2#

这里有两个方法:
方法1:反复调用random.choice,直到得到你想要的结果。这有点傻,而且可以说是不好的做法,但它确实有效。但你必须确保有一个可能的有效结果,否则它将陷入无限循环。

import random

words = "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"
sentence_length = 20

sentence1 = []

# first method: ignore bad results
for n in range(sentence_length):
    next_word = random.choice(words)
    while next_word in sentence1[-4:]:
        # print is for your understanding:
        print("  " + " ".join(sentence1) + " -> skipping " + next_word)
        next_word = random.choice(words) 
    sentence1.append(next_word)

print(" ".join(sentence1))

方法2:从random.choice的可用单词列表中删除不需要的单词。

# second method: remove unwanted words from allowed set
# note: this method removes multiplicity! If you want some words to be more likely, don't use sets
words_set = {x for x in words}
sentence2 = []
for n in range(sentence_length):
    valid_words = words_set.difference(sentence2[-4:])
    next_word = random.choice(list(valid_words))
    sentence2.append(next_word)

print(" ".join(sentence2))

# alternatively: using just list, not sets
# this preserves multiplicity, but *might* run slower if your list of words is very large
sentence3 = []
for n in range(sentence_length):
    valid_words = [w for w in words if w not in sentence3[-4:]]
    next_word = random.choice(list(valid_words))
    sentence3.append(next_word)

print(" ".join(sentence3))
oogrdqng

oogrdqng3#

你可以添加列表并像队列一样使用它
新代码是

import random
import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.geometry('300x200')

queue = []
def func():
    global queue
    a = "Word A1", "Word A2", "Word A3", "Word A4", "Word A5", "Word A6", "Word A7", "Word A8"
    print("NEW")
    while True:
        # geting random word
        a_random = random.choice(a)
        # check for repitaion
        if not a_random in queue:
            # print word
            print(a_random)
            # push the word into the queue to stop repitaion
            queue.append(a_random)
            #check if after 4 word to allow repitaion word
            if len(queue) == 5:
                queue.pop(0)
            break

    print(" ")
    return a_random

button = ttk.Button(root, text='Random', command=func)
button.place(x=10, y=10)

root.mainloop()

如果您不熟悉队列,请检查此website

4xrmg8kj

4xrmg8kj4#

deque可以配置最大长度,以自动跟踪最后四个字。示例:

>>> from collections import deque
>>> last = deque(maxlen=4)
>>> last.append('word2')
>>> last.append('word3')
>>> last.append('word4')
>>> last.append('word5')
>>> last.append('word6')
>>> last.append('word6')
>>> last    # only remembers last 4 added
deque(['word3', 'word4', 'word5', 'word6'], maxlen=4)

这可用于跟踪最后选择的单词并重试选择:

import random
from collections import deque

_last4 = deque(maxlen=4)
words = ['Word A1', 'Word A2', 'Word A3', 'Word A4', 'Word A5', 'Word A6', 'Word A7', 'Word A8']

def get_word():
    # Assignment expression (:=) needs Python 3.8+
    while (word := random.choice(words)) in _last4:
        pass
    _last4.append(word)
    return word

for _ in range(20):
    w = get_word()
    print(f'{w}   #{" "*int(w[-1])}{w[-1]}') # with annotation

输出(注解为调出间距):

Word A2   #  2
Word A1   # 1
Word A6   #      6
Word A8   #        8
Word A3   #   3
Word A7   #       7
Word A1   # 1
Word A4   #    4
Word A2   #  2
Word A3   #   3
Word A8   #        8
Word A1   # 1
Word A6   #      6
Word A4   #    4
Word A3   #   3
Word A7   #       7
Word A8   #        8
Word A6   #      6
Word A2   #  2
Word A1   # 1

Tk示例:

import random
import tkinter as tk
from tkinter import ttk
from collections import deque

_last4 = deque(maxlen=4)
words = ['Word A1', 'Word A2', 'Word A3', 'Word A4', 'Word A5', 'Word A6', 'Word A7', 'Word A8']

def get_word():
    # Assignment expression (:=) needs Python 3.8+
    while (word := random.choice(words)) in _last4:
        pass
    _last4.append(word)
    label.configure(text=word)

root = tk.Tk()
root.geometry('300x200')

label = ttk.Label(root)
label.place(x=10, y=50)
button = ttk.Button(root, text='Random', command=get_word)
button.place(x=10, y=10)

root.mainloop()
u3r8eeie

u3r8eeie5#

您可以尝试利用random.sample来减少重复(尽管它可能不完全符合您的要求,但可以“足够好”,并且应该更快):
返回从总体序列中选择的唯一元素的k长度列表。用于不替换的随机抽样。

a = ["Word A1", "Word A2", "Word A3", "Word A4", "Word A5", "Word A6", "Word A7", "Word A8"]

window_size = 4 # should be less then size of a
curr_window = random.sample(a, window_size) # 4 random unique elements from a

# use curr_window for the next 4 random values then renew it with random.sample(a, 4)

请注意,由于“窗口”边界(即“1,2,3,4,4,不是4,不是4,不是4,...”),您仍然可以重复

UPD

例如(可以 Package 成像iterator这样的类):

a = ["Word A1", "Word A2", "Word A3", "Word A4", "Word A5", "Word A6", "Word A7", "Word A8"]

window_size = 4
curr_window = random.sample(a, window_size)
curr = -1

def get_word():
   global curr, curr_window
   curr = curr + 1
   if(curr >= window_size):
       curr = 0
       curr_window = random.sample(a, window_size)
   return curr_window[curr]    

root = tk.Tk()
root.geometry('300x200')

def func():
   print("NEW")
   a_random = print(get_word())
   print(" ")  
   return a_random

button = ttk.Button(root, text='Random', command=func)
button.place(x=10, y=10)

root.mainloop()

相关问题