Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Hallo!
Vom folgenden Code erwarte ich, dass die Liste joker_lists um die ABC-Buchstaben angewachsen ist. Was mit print(letter_list) ausgegeben wird, ist korrekt. Dies hänge ich an die Liste joker_lists an. Sie enthält diese Elemente am Ende aber nicht, warum?
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 14 09:21:25 2021
@author: User
"""
letters = 'öl tze'
alphabet = 'abcdefghijklmnopqrstuvwxyzäöü'
letter_list = []
for single_letter in letters:
letter_list.append(single_letter)
joker_list = []
if " " in letters:
for i, alphabet_letter in enumerate(alphabet):
letter_list.append(alphabet_letter)
for j, alphabet_letter in enumerate(alphabet):
letter_list.append(alphabet_letter)
print(letter_list)
joker_list.append(letter_list)
letter_list.pop()
letter_list.pop()
for item in joker_list:
print(item)
print(len(joker_list))
liste = []
mehr_liste = [liste, liste, liste]
print(mehr_liste)
liste.append("ich soll keine Referenzen auf Datenstrukuren behandeln, als ob sie Kopien waeren")
print(mehr_liste)
liste.clear()
print(mehr_liste)
Sowas ist der Grund, warum man Datenstrukturen nicht irgendwie mit append/pop/clear & co massiert, sondern stattdessen neu aufbaut, und dann im Zweifel an den alten Namen bindet. Weil das voellig unuebersichtlich wird.
Jedes letter_list append hat ein pop. letter_list ist also am Ende deiner Schleife wieder unveraendert. Und in joker_list hast du halt nur eine Referenz auf letter_list, keine der temporaeren Aenderungen wirkt sich aus. Wenn du die *Elemente* der letter_list in joker_list haben willt, dann brauchst du extend statt append. Ob das richtig ist? KA. Ich begreife nicht, was das alles soll.
1. Wir kommen der Sache näher mit dem, was du sagst. Zunächst zu extend statt append: Das ist es nicht, denn so würde die Liste 7569 lang. Aber mich interessiert, was du bzgl. Referenz und "keine Änderung wirkt sich nicht aus" gesagt hast. Wie muss das Programm denn aussehen, damit joker_list die 841 'Listchen' enthält?
2. Es gibt eine 223-zeilige voll lauffähige Version des Programmes. Ziel heute war, das darin verletzte DRY-Prinzip in der Funktion get_hints() zu bessern. Soll ich dieses ganze Programm mal posten?
Grüße
Der Fehler ist, dass Du nicht 841 Listen hast, sondern nur EINE. Und diese EINE ist 841mal in der jocker_list-Liste.
Damit solche Fehler nicht auftreten, ist die einfache Regel, niemals Listen zu verändern, sondern immer neue Listen zu erzeugen.
letters = 'öl tze'
alphabet = 'abcdefghijklmnopqrstuvwxyzäöü'
letter_list = list(letters)
joker_list = []
if " " in letters:
for alphabet_letter1 in alphabet:
for alphabet_letter2 in alphabet:
joker_list.append(letter_list + [alphabet_letter1, alphabet_letter2])
for item in joker_list:
print(item)
print(len(joker_list))
from itertools import combinations_with_replacement
letters = 'öl tze'
alphabet = 'abcdefghijklmnopqrstuvwxyzäöü'
joker_list = []
for alphabet_letters in combinations_with_replacement(alphabet, letters.count(' ')):
word = letters
for letter in alphabet_letters:
word = word.replace(' ', letter, 1)
jocker_list.append(word)
Hallo!
Verstehe ich das richtig? In dem Moment, wo der alphabet_letter mit letter_list.pop() wieder aus der Liste letter_list weggenommen wird, wird er auch aus der joker_list weggenommen? Gibt es denn keinen Operator, der die Liste autonom macht?
Grüße, Strawk
Hallo!
Ich habe seit 1994 eine Stoffwechselstörung im Gehirn; das Lernen fällt mir extrem schwer. Mit Python arbeite ich seit 2017/2018. Das habe ich in den letzten Wochen gemacht:
#!/usr/bin/env python
# coding: utf-8 -*-
#-------------------------------------------------------------------------------
# Name: scrabble.py
# Purpose: create german words with given letters
# optional: get words that fit at position(s) with certain letters(s)
# optional: consider if there's a joker or two
#
# Author: ---
#
# Created: 07/13/2021
# License: n/a
#-------------------------------------------------------------------------------
"""
create german words with given letters
and write them into a file
for use in the board game "Scrabble"
1 main class that, beside constructor, contains 3 private functions
and 1 public function:
constructor (__init__):
creates a set with all german words
(over 2 million) by reading file
3 private functions:
_calc_permutations:
creates a list of all possible permutations (combinations) of
given letter-record
In: letters
Out: all_permutations
_create_results:
creates the result-lists
depending of filter instructions are given,
calls _filter_on_position
In: all_permutations, all_words
Out: total_result
_filter_on_position:
filters existing words for desired single letters and
their desired position
In: results, filter_dict
Out: results (filtered)
1 public function:
get_hints:
calculate the joker-options by calling the functions
_calc_permutations and _create_results the necessary times
and thus get word-hints for the player
In: filter_dict, letters
"""
import os
from itertools import chain, permutations
import time
# main class
class Letter_record():
def __init__(self, filename):
"""
creates a set with all german words (over 2 million)
by reading file
In:
filename
Out:
all_words
"""
all_words = set()
dic = open(filename, 'r')
for line in dic:
all_words.add(line.strip())
self.all_words = all_words
# private functions:
def _calc_permutations(self):
"""
creates a list of all possible permutations (combinations) of
given letter-record
In:
letters
Out:
all_permutations
"""
chars = []
for i in self.letters:
if i == ' ':
self.letters.remove(i)
for c in self.letters:
chars.append(c)
all_permutations = list(
chain.from_iterable(
permutations(chars, length)
for length in range(1, len(chars) + 1)
)
)
self.all_permutations = all_permutations
def _create_results(self):
"""
creates the result-lists
depending on filter instructions are given, calls _filter_on_position
In:
all_permutations, all_words
Out:
total_result
"""
results = []
for item in self.all_permutations:
word = "".join(item)
for possible_word in [word, word.capitalize()]:
if possible_word in self.all_words:
if possible_word not in results and possible_word not in self.total_result:
results.append(possible_word)
self.results = results
if len(self.filter_dict) != 0:
self._filter_on_position()
self.total_result.extend(self.results)
def _filter_on_position(self):
"""
filters existing words for desired single letters and
their desired position
In:
results, filter_dict
Out:
results (filtered)
"""
filtered_words = []
for word in self.results:
# ensure all filter conditions take effect, no matter how many
all_filter_conditions = 0
for position, letter in self.filter_dict.items():
try:
if word[position] == letter or word[position] == letter.capitalize():
all_filter_conditions += 1
except:
continue
if all_filter_conditions == len(self.filter_dict):
filtered_words.append(word)
self.results = filtered_words
#public function
def get_hints(self, letters='öl tze', filter_dict={0 : 'ö', 1 : 'l', 2 : 'g', 3 : 'ö', 4 : 't', 5 : 'z'}):
"""
calculate the joker-options by calling the functions
_calc_permutations and _create_results the necessary times
and thus get word-hints for the player
In:
filter_dict, letters
"""
self.filter_dict = filter_dict
self.letters = letters
self.total_result = []
alphabet = 'abcdefghijklmnopqrstuvwxyzäöü'
# turn string into list
letter_list = []
for single_letter in self.letters:
letter_list.append(single_letter)
# important here: 2 space-characters
if " " in letters:
for i, alphabet_letter in enumerate(alphabet):
letter_list.append(alphabet_letter)
for j, alphabet_letter in enumerate(alphabet):
letter_list.append(alphabet_letter)
self.letters = letter_list
self._calc_permutations()
self._create_results()
# prevent letter-list from increasing inner loop
letter_list.pop()
# prevent letter-list from increasing outer loop
letter_list.pop()
elif " " in letters:
for i, alphabet_letter in enumerate(alphabet):
letter_list.append(alphabet_letter)
self.letters = letter_list
self._calc_permutations()
self._create_results()
# prevent letter-list from increasing
letter_list.pop()
elif " " not in letters:
self._calc_permutations()
self._create_results()
def main():
def write_to_file(total_result):
try:
os.mkdir('results')
except:
pass
resultfile = open('results/results.txt','w+')
for result_counter, word in enumerate(total_result):
# suppress line feed at EOF
if result_counter + 1 == len(total_result):
resultfile.write("%d: %s" % (result_counter + 1, word))
else:
resultfile.write("%d: %s\n" % (result_counter + 1 , word))
resultfile.close()
set_a = Letter_record('wordbooks/german.dic')
set_a.get_hints()
write_to_file(set_a.total_result)
del set_a
if __name__ == "__main__":
start = time.time()
main()
ende = time.time()
print('program took {:5.3f} minutes'.format((ende-start)/60))