0
hidden_word = ""
for c in word:
     hidden_word += c if c in guesses else'-'
return hidden_word

I'm trying to accomplish this in a single line of code using list comprehension but am having troubles getting an if-else condition to work and think i am missing something. basically if word = 'yes' and guesses contains 'e' then the result should be '-e-'. I'm able to appropriately put the letter but am having trouble with the logic to put the '-' if the letter is not in guesses.

2
  • This should work, what problem are you having? Commented Oct 30, 2017 at 22:36
  • hidden_word = ''.join(c if c in guesses else '-' for c in word). Commented Oct 30, 2017 at 22:41

1 Answer 1

4

I think your code is fine - it gets the point across. Why use a list comprehension (and then convert that back to a string)?

hidden_word = ''.join([c if c in guesses else '-' for c in word])

Is that really better? You could change it to a generator expression, but still...

hidden_word = ''.join(c if c in guesses else '-' for c in word)

EDIT: Testing this with a 1000 character "word" using:

import timeit
setup = """import random
chars = "abcdefghijklmnopqrstuvwxyz"
s = "".join(random.choice(chars) for _ in range(1000))
guesses = "agjoxwz"
"""

t1 = "hidden_word = ''.join([c if c in guesses else '-' for c in s])"
t2 = "hidden_word = ''.join(c if c in guesses else '-' for c in s)"
t3 = """hidden_word = ""
for c in s:
     hidden_word += c if c in guesses else '-'"""

Results:

In [24]: timeit.timeit(setup=setup, stmt=t1)
Out[24]: 100.88796829901968

In [25]: timeit.timeit(setup=setup, stmt=t2)
Out[25]: 147.86355467070305

In [26]: timeit.timeit(setup=setup, stmt=t3)
Out[26]: 247.9441536138757

Whoa. So the list comprehension is in fact must faster (and better than a generator expression).

With only 50 letters per "word", the differences are less pronounced, but the list comprehension still wins:

In [28]: timeit.timeit(setup=setup, stmt=t1)
Out[28]: 5.416419290962722

In [29]: timeit.timeit(setup=setup, stmt=t2)
Out[29]: 7.828715333297168

In [30]: timeit.timeit(setup=setup, stmt=t3)
Out[30]: 7.984714775332918
Sign up to request clarification or add additional context in comments.

3 Comments

Using +/+= for string concatenation in a loop like this can be inefficient if the strings are lengthy. That's one reason to prefer ''join() on a sequence. Perhaps the strings are short and performance is not an issue, in which case the more readable solution is better.
@mhawke: I seem to remember that string "adding" has become much more efficient in recent versions of Python, and that ''.join()'s speed advantage is gone. But I need to test this.
@mhawke: I was wrong. Adding is in fact much worse on long strings. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.