Почему возникает ошибка «can only join an iterable» при повторном прохождении цикла? И как сравнить имя пользователя с именем ключа словаря?
Здравствуйте. Пишу терминальную игрушку по угадыванию числа. Первая проблема возникла на этапе логина (при вводе он пишет, что такого пользователя нет, хотя он есть, а дальше сохраняет (т.е. тупо перезаписывает) его), таким образом каждую игру очки пользователя окончательно сбрасываются. И вторая, как по мне, более критичная — в конце цикла (т.е. при выигрыше или проигрыше) пользователю предлагают, грубо говоря, выйти из игры, сменить пользователя или продолжить игру с текущим именем. При выборе последнего варианта вылетает ошибка при подсчете очков:
scoreN = ("".join(dic[key])) TypeError: can only join an iterable
хотя в первоначальном варианте ее не возникало. Так же ошибка отсутствует, если поменять имя пользователя.
Вот код:
#******************* ИМПОРТ КАТАЛОГОВ ******************************************************************************************* import sys import json import random import msvcrt #****************** ОБЪЯВЛЕНИЕ ГЛОБАЛЬНЫХ ПЕРЕМЕННЫХ И КЛАССОВ ******************************************************************* dic = <> class Igrok(): name = 'imya' score = 0 i = 0 polsovatel = Igrok() polsovatel.i = 0 #polsovatel.name chislo = '-1' min = -1 max = -1 n = -1 z = -1 name = ' ' key = ' ' #****************** ФУНКЦИИ ****************************************************************************************************** #*** Ввод имени пользователя *** def NewIgra(): global polsovatel global name global dic polsovatel.name = input("Введите имя игрока ") Proverka() Random() #*** Логика игры *** def Logika(): global polsovatel global name global chislo global z global dic global min global max print(polsovatel.name)#DEBAG while polsovatel.i!=(int(n)): if int(chislo) != int(z): try: # Отлавливаем ошибки ввода (а именно, буквам нет!) chislo = int(input("Введите загаданное число ")) except ValueError: print("Ошибка ввода! ") chislo = input("Пожалуйста, введите ЧИСЛО еще раз ") if chislo < min or chislo >max: print("Число выходит за пределы заданного вами диапазона!") chislo = input("Введите число еще раз ") if int(chislo) < int(z): print("Слишком мало!") polsovatel.i+=1 print(polsovatel.i) if int(chislo) >int(z): print("Слишком много!") polsovatel.i+=1 print(polsovatel.i) if int(chislo) == int(z): key = polsovatel.name scoreN = ("".join(dic[key])) print(scoreN)#DEBAG print(dic[key]) #DEBAG polsovatel.score = int(scoreN) + (int(n)-polsovatel.i)*2 scoreS = polsovatel.score - int(scoreN) dic[key] = polsovatel.score print(polsovatel.name, ", вы выиграли! Ваши очки за игру: ", scoreS) print("Ваше общее количество очков: ", polsovatel.score) print("Ваши очки сохранены!") print(dic[key])#DEBAG Exit() else: print("У вас закончиличь попытки, вы проиграли!") key = polsovatel.name if dic[key] >= 10: scoreN = ("".join(dic[key])) polsovatel.score = int(scoreN) - 10 dic[key] = polsovatel.score print(polsovatel.name, " вы оштрафованы на 10 очков. Ваш баланс: ", polsovatel.score) print(dic[key]) #DEBAG Exit() #*** Выход или продолжение игры *** def Exit(): print ("\nНажмите для закрытия окна или любую клавишу для продолжения игры") kay = ord(msvcrt.getch()) if kay == 27: # ESC print("Программа завершена") Save() sys.exit() PodMenu() #*** Поиск и запись пользователя в базу *** def Proverka(): #! global polsovatel global name global dic if name.find(polsovatel.name) != -1 : #Если имя пользователя есть в словаре начинаем игру print("Игра началась!") else: dic[polsovatel.name] = '0' #Если нет - добавляем print("Пользователь сохранен") print(dic) #*** Выборы для подменю *** def Punkt(): try: punkt = int(input()) if punkt == 1: Menu() if punkt == 2: Random() if punkt == 3: NewIgra() else: print("Такой пункт отсутствует! Повторите ввод!") Punkt() except ValueError: print("Не верный формат ввода! Введите ЧИСЛО для продолжения сценария") Punkt() #*** Подменю *** def PodMenu(): print("Выберите что хотите сделать: ") print("Нажмите 1 для перехода в главное меню ") print("Нажмите 2 для продолжения игры с введенным именем пользователя ") print("Нажмите 3 для смены имени ") Punkt() #*** Выгрузка*** def Slovar(): global polsovatel global name global dic #Выгрузка таблицы очков из файла в словарь: with open('C:\\Users\\Professional\\Desktop\\Tokarev\\table.txt', 'r', encoding='utf-8') as file: #Читаем файл indata = file.read().splitlines() # read().splitlines() - чтобы небыло пустых строк """for line in indata: # Проходимся по каждой строчке key, *value = line.split() #Разбиваем строку по пробелам dic[key] = value # Добавляем в словарь name = (', '.join(list(dic))) #Конвертируем имена ключей в строку""" # проходим в цикле по списку строк for i in indata: # присваиваем переменным k и v левую и правую часть подстроки, # разделяя по символу ':' k, v = i.split(': ') # убираем лишние концевые пробелы v = v.strip() # определяем, является ли значение переменной v числом, и если да, то # преобразуем к целому числу, иначе оставляем строкой v = int(v) if v.isdigit() else v # добавляем в словарь соответствующие пары ключ:значение dic[k] = v print(list(dic)) #DEBAG #*** Сохранение игры *** def Save(): global dic with open('C:\\Users\\Professional\\Desktop\\Tokarev\\table.txt', 'w', encoding='utf-8') as file: #Открываем файл на запись for key,val in dic.items(): file.write('<>: <>\n'.format(key,val)) #************************************ Сама программа ****************************************** Slovar() Menu()
- Вопрос задан более двух лет назад
- 1377 просмотров
1 комментарий
Простой 1 комментарий
Вызов ».join ведёт к ошибке: TypeError: can only join an iterable
str.join(iterable) ожидает в качестве аргумента iterable — объект поддерживающий итерирование.
iterable An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list , str , and tuple ) and some non-sequence types like dict , file objects, and objects of any classes you define with an __iter__() or __getitem__() method. Iterables can be used in a for loop and in many other places where a sequence is needed ( zip() , map() , . ). When an iterable object is passed as an argument to the built-in function iter() , it returns an iterator for the object. This iterator is good for one pass over the set of values. When using iterables, it is usually not necessary to call iter() or deal with iterator objects yourself. The for statement does that automatically for you, creating a temporary unnamed variable to hold the iterator for the duration of the loop. See also iterator, sequence, and generator.
по простому на русском (c) @jfs:
».join() принимает составной объект—коллекцию строк, такую как список, которую можно в for-цикл передать, чтобы все строки обойти
Вот один из способов определения является ли объект итерируемым и заодно примеры итерируемых объектов:
In [1]: import collections In [2]: isinstance(['a','b'], collections.Iterable) Out[2]: True In [3]: isinstance('ab', collections.Iterable) Out[3]: True In [4]: isinstance('a', collections.Iterable) Out[4]: True In [5]: isinstance([1,2], collections.Iterable) Out[5]: True In [6]: isinstance(1, collections.Iterable) Out[6]: False # NOT iterable In [7]: isinstance((1), collections.Iterable) Out[7]: False # NOT iterable In [8]: isinstance((1,), collections.Iterable) Out[8]: True In [9]: isinstance(, collections.Iterable) Out[9]: True In [10]: isinstance(<>, collections.Iterable) Out[10]: True In [11]: isinstance(set([1]), collections.Iterable) Out[11]: True In [12]: isinstance(set(), collections.Iterable) Out[12]: True In [13]: isinstance(open('d:/temp/aaa.txt', 'w'), collections.Iterable) Out[13]: True
«Can only join an iterable» python error
I’ve already looked at this post about iterable python errors: «Can only iterable» Python error But that was about the error «cannot assign an iterable». My question is why is python telling me:
"list.py", line 6, in reversedlist = ' '.join(toberlist1) TypeError: can only join an iterable
I don’t know what I am doing wrong! I was following this thread: Reverse word order of a string with no str.split() allowed and specifically this answer:
>>> s = 'This is a string to try' >>> r = s.split(' ') ['This', 'is', 'a', 'string', 'to', 'try'] >>> r.reverse() >>> r ['try', 'to', 'string', 'a', 'is', 'This'] >>> result = ' '.join(r) >>> result 'try to string a is This'
and adapter the code to make it have an input. But when I ran it, it said the error above. I am a complete novice so could you please tell me what the error message means and how to fix it. Code Below:
import re list1 = input ("please enter the list you want to print") print ("Your List: ", list1) splitlist1 = list1.split(' ') tobereversedlist1 = splitlist1.reverse() reversedlist = ' '.join(tobereversedlist1) yesno = input ("Press 1 for original list or 2 for reversed list") yesnoraw = int(yesno) if yesnoraw == 1: print (list1) else: print (reversedlist)
The program should take an input like apples and pears and then produce an output pears and apples. Help would be appreciated!
TypeError: can only join an iterable
Я вывожу слова из списка по цифре, но если студента нету, то хочу сделать надпись Error 404 ,но оно ругается, хотя слово пишет.
File «C:\Users\Asus\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py», line 1883, in __call__
return self.func(*args)
File «C:/Users/Asus/PycharmProjects/untitled4/venv/test3.py», line 25, in fav_stud
name[‘text’] = ‘ ‘.join(s)
TypeError: can only join an iterable
А когда ставлю return, то
1 2 3 4 5 6 7 8 9 10
def fav_stud(): c = ['Error 404'] n = int(enter.get()) cur.execute("SELECT name FROM Students ORDER BY name") for i in range(0, n): s = cur.fetchone() name['text'] = ' '.join(s) if n > 3: name['text'] = ' '.join(c) return
уже ошибку не показывает. Я совершенно случайно разобрался с ошибкой, но сам не пойму почему она не показывается. Пересмотрел видео про команду return, но так не понял.