30
votes

Say I have a string s = 'BINGO'; I want to iterate over the string to produce 'B I N G O'.

This is what I did:

result = ''
for ch in s:
   result = result + ch + ' '
print(result[:-1])    # to rid of space after O

Is there a more efficient way to go about this?

4
On my machine, this takes about 500ns. Is that really a bottleneck in your program? If not, don't ask about efficiency; ask about simplicity, readability, etc.—things that actually matter. - abarnert
@abarnert perhaps efficient means something particular to you, but it doesn't actually necessarily mean machine efficiency. - kojiro
@kojiro: "efficient" means something particular in the disciple/profession/hobby/etc. of computer programming, which is what this site is about, so that's the definition that matters. That's why this site has an efficiency tag that's intended and used for exactly that purpose. - abarnert
Yes, @abarnert's right -- the problem with this solution isn't first of all that it's inefficient, it's that it's not Pythonic and not simple. ' '.join(s) is the simple, Pythonic way. However, efficiency is a concern, as the above solution will be O(N^2), whereas the join is O(N) -- this won't matter for 'BINGO' but will matter for long strings. - Ben Hoyt
@BenHoyt: The reason it looks linear with smallish strings is that copying a string is basically just a call to memmove—which still loops, of course, but it does so in C code that's usually highly optimized for the platform (especially on x86, which has opcodes specifically designed to speed up memmove). So, the constant multiplier on the second N is orders of magnitude smaller than the one on the first, which makes it hard to see until N gets very large. - abarnert

4 Answers

60
votes
s = "BINGO"
print(" ".join(s))

Should do it.

25
votes
s = "BINGO"
print(s.replace("", " ")[1: -1])

Timings below

$ python -m timeit -s's = "BINGO"' 's.replace(""," ")[1:-1]'
1000000 loops, best of 3: 0.584 usec per loop
$ python -m timeit -s's = "BINGO"' '" ".join(s)'
100000 loops, best of 3: 1.54 usec per loop
3
votes

The Pythonic way

A very pythonic and practical way to do it is by using the string join() method:

str.join(iterable)

The official Python documentations says:

Return a string which is the concatenation of the strings in iterable... The separator between elements is the string providing this method.

How to use it?

Remember: this is a string method.

This method will be applied to the str above, which reflects the string that will be used as separator of the items in the iterable.

Let's have some practical example!

iterable = "BINGO"
separator = " " # A whitespace character.
                # The string to which the method will be applied
separator.join(iterable)
> 'B I N G O'

In practice you would do it like this:

iterable = "BINGO"    
" ".join(iterable)
> 'B I N G O'

But remember that the argument is an iterable, like a string, list, tuple. Although the method returns a string.

iterable = ['B', 'I', 'N', 'G', 'O']    
" ".join(iterable)
> 'B I N G O'

What happens if you use a hyphen as a string instead?

iterable = ['B', 'I', 'N', 'G', 'O']    
"-".join(iterable)
> 'B-I-N-G-O'
-1
votes

The most efficient way is to take input make the logic and run

so the code is like this to make your own space maker

need = input("Write a string:- ")
result = ''
for character in need:
   result = result + character + ' '
print(result)    # to rid of space after O

but if you want to use what python give then use this code

need2 = input("Write a string:- ")

print(" ".join(need2))