0

I'm trying to make a list of 'blanks' that can be filled in individually later. The length of the list is dependent on a value (currentWord) which is why I can't hard-code it.

iter8 = len(currentWord)
for i in currentWord:
    answerListNEW.append(' ')
    #
for i in currentWord:
    answerListNEW[i] = '_'

I get errors that the index must be integer, not str. Is there a way for the program to accept the 'blank space' ? For simplicity, lets say currentWord = 'alpha' so that it's simple and there's just 5 iterations.

SECONDLY, I would also like to print that list as a concatenated string so it's just '_____'. (That way when values are added it becomes 'v' and such.

Thanks in advance!!

  • 1
    Welcome to Stack Overflow.Where the code says `for i in currentWord:`, what values do you expect `i` to have each time through the loop? Why? Did you try to check what the values are? Have you tried following a Python tutorial in order to understand such fundamentals? – Karl Knechtel Jun 10 '22 at 15:38
  • 4
    I also don't understand the approach to the problem. Instead of adding spaces to the (initially empty) list and then replacing them with underscores, why not just add underscores to the list instead? – Karl Knechtel Jun 10 '22 at 15:39
  • 1
    I suggest adding `print(i)` to see what `i` is. You might even need to do `print('*', i, '*') – Code-Apprentice Jun 10 '22 at 15:39
  • 4
    `answerListNEW = [' '] * len(currentWord)` (or `['_'] * len(currentWord)` to get the end result directly)? That said, presizing is frowned upon (it's usually less performant than just calling `.append` on demand), so it's rare you want to do it. – ShadowRanger Jun 10 '22 at 15:39
  • 2
    What is the `iter8` variable for? Did you consider using that? – Barmar Jun 10 '22 at 15:39
  • 2
    Why not just something like `answerListNew = ['_'] * len(currentWord)`? – The Photon Jun 10 '22 at 15:39
  • As for joining, that's just [`''.join(list_of_strings)`](https://stackoverflow.com/q/1316887/364696). – ShadowRanger Jun 10 '22 at 15:44
  • `list('_' * len(currentWord))` – Peter Wood Jun 10 '22 at 15:45
  • @PeterWood: Typically more efficient to make the template of the final type (`[' ']` or `list('_')` as you prefer) first, *then* multiply. Multiplying first, then converting, means you need two huge sequences, and you have to read the entirety of the temporary sequence to initialize the final one (making `str`'s iterator keep recreating the `'_'` object over and over when `list` could have directly copied a single pointer to the expanded `list` and directly applied all `len(currentWord)` refcnt increments in a single bulk operation). – ShadowRanger Jun 10 '22 at 15:49
  • The efficiency of multiplying first gets truly horrible when you're using a character outside of whatever your implementation's singleton cached character limit is (for CPython, it's Latin-1, caching all len `1` strings with `ord` values below 256). Because the `str` iterator will make *new* objects for each of those `len` one `str`s, and now you're storing `len(currentWord)` separate instances (on 64 bit CPython, with `chr(256)` as the template, you'd go from `8 * len(currentWord)` bytes of overhead per item to `84 * len(currentWord)` bytes of overhead). – ShadowRanger Jun 10 '22 at 15:54
  • @ShadowRanger I don't know about implementation details. – Peter Wood Jun 10 '22 at 15:54
  • 1
    @PeterWood: The second comment is all implementation details. But the first comment (aside from the refcnt update note that is CPython specific) is not an implementation detail; you'd have the same problem on all existing interpreters. You'd need a ridiculously sophisticated and flexible optimizer to fix that pattern (while still falling back to the slow version when `list` is replaced or the integer you're multiplying by isn't a true `int` or the like). Python is too dynamic for that. In short, it's a general rule, not specific to implementation details; convert first, then multiply. – ShadowRanger Jun 10 '22 at 16:01

2 Answers2

2

i in currentWord will iterate over letters of that string (assuming it is a string). As the error says, lists cannot be indexed by letters.

You can use range()

answerListNEW = ['_' for _ in range(len(currentWord))]

Or list multiplication

answerListNEW = ['_'] * len(currentWord)

Or "listing" a string of all underscores

answerListNEW = list('_' * len(currentWord))

also like to print that list as a concatenated string

print(''.join(answerListNEW))
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • 3
    `answerListNEW = ['_' for _ in currentWord]` or `['_'] * len(currentWord)` are probably cleaner. – norok2 Jun 10 '22 at 15:42
  • @norok2: Yeah, if you use a normal `for` loop, you need the indices, but if you're going to switch to a listcomp anyway, you won't be using them so no need to generate them. – ShadowRanger Jun 10 '22 at 15:45
  • @ShadowRanger the standard way to generate indices is using [**`enumerate`**](https://docs.python.org/3/library/functions.html#enumerate). – Peter Wood Jun 10 '22 at 15:50
  • 1
    @PeterWood: I'm aware. Not sure how that's relevant here though? The moment you don't need indices, don't make 'em; doesn't matter if you can more efficiently/Pythonically generate things you don't need. – ShadowRanger Jun 10 '22 at 15:56
0

I would also like to print that list as a concatenated string so it's just '_____'

A string has most of the same properties as a list already, so why bother making the list, only to convert it to a string.

You can just do something like

answerListNew = '_' * len(currentWord)

if you want a string the same length as currentWord containing all '_' characters.

For an actual list of letters (allowing you to modify the letters one by one), you can do

answerListNew = ['_'] * len(currentWord)

and convert it to string form with

answerStrNew = ''.join(answerListNew)
The Photon
  • 1,242
  • 1
  • 9
  • 12
  • 1
    I think they want to be able to gradually add letters. – Peter Wood Jun 10 '22 at 15:48
  • @OneCricketeer, for the length of the string you're going to be using in a hangman game, just generating a new string each time you fill in a blank isn't going to be a significant memory problem. – The Photon Jun 10 '22 at 15:48
  • @PeterWood, they're still going to have to generate a new string from each new list of letters in order to print it out... – The Photon Jun 10 '22 at 15:52
  • @ThePhoton where are you going to store the guesser's progress? – Peter Wood Jun 10 '22 at 15:52