Harvey
Harvey

Reputation: 114

.join() returns unexpected string

from random import randint
roomTypes = ['T|', 'M|', 'W|', 'H|', 'C|']
dungeonLayout = ''
for i in range(1,10):
    dungeonLayout = dungeonLayout.join(roomTypes[randint(0, 4)])
print('Room types are Temple |T|, Abandoned Military Base |M|, Wizard\'s Abodes |W|, House |H|, Church |C|')
print('_____________________________')
print('|' + dungeonLayout)
print('_____________________________')`

My code (which is shown above) is meant to return a random list of the rooms, this sort of works, however instead of the rooms being formatted like this:

|W|H|

it prints:

|WH||

I am curious as to why this is and was wondering if I'm using the join command wrong or if I should be using a different command altogether.

Upvotes: 0

Views: 280

Answers (10)

Borris Wiria
Borris Wiria

Reputation: 476

str.join(iterable)

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

src=https://docs.python.org/2/library/stdtypes.html#str.join

so, from the explanation.. it returns the concatenation of strings in iterable iterable.

if you want your desired result, simply do:

dungeonLayout = dungeonLayout + roomTypes[randint(0,4)]

Upvotes: 0

Richard Guy
Richard Guy

Reputation: 80

A couple of options...

The simplest is to use the + operator to concatenate each new room to your string:

dungeonLayout = dungeonLayout + roomTypes[randint(0, 4)]

But you're right, the join() method works slightly differently to this. The argument should be a sequence of strings, which are concatenated using the string as the separator, i.e.

separator = '|'
myList = ['1', '2', '3']
print(separator.join(myList))

gives

1|2|3

So to use join() in your case:

from random import randint
roomTypes = ['T', 'M', 'W', 'H', 'C']
roomList = []
for i in range(1,10):
    roomList.append(roomTypes[randint(0, 4)])
dungeonLayout = '|'.join(roomList) + '|'
print('Room types are Temple |T|, Abandoned Military Base |M|, Wizard\'s Abodes |W|, House |H|, Church |C|')
print('_____________________________')
print('|' + dungeonLayout)
print('_____________________________')

Hope that helps!

Upvotes: 0

hashcode55
hashcode55

Reputation: 5860

Its because of this line -

for i in range(1,10):
    dungeonLayout = dungeonLayout.join(roomTypes[randint(0, 4)])

You are modifying dungeonLayout and using it again to join the list.

What you should do -

dungeonLayout = ''.join([roomTypes[randint(0, 4)] for _ in range(10)])

Upvotes: 4

Harvey
Harvey

Reputation: 114

dungeon_layout = '|' + ''.join(random.choice(room_types) for _ in range(15))

The code above replaces the for loop that I added and fixes the problem and returns the correct amount of rooms, credit goes towards @jDo, thanks a lot.

Upvotes: 1

Umar
Umar

Reputation: 166

Its very simple edit, just change

dungeonLayout = dungeonLayout.join(roomTypes[randint(0, 4)])

to

dungeonLayout = dungeonLayout + roomTypes[randint(0, 4)]

Instead of using join, just use + Here is full program

from random import randint
roomTypes = ['T|', 'M|', 'W|', 'H|', 'C|']
dungeonLayout = ''
for i in range(1,10):
    dungeonLayout = dungeonLayout + roomTypes[randint(0, 4)]
print('Room types are Temple |T|, Abandoned Military Base |M|, Wizard\'s Abodes |W|, House |H|, Church |C|')
print('_____________________________')
print('|' + dungeonLayout)
print('_____________________________')
rand1 = randint(0, 4)

Ex Output: |T|W|M|M|W|M|C|H|T|

Upvotes: 0

Chase G.
Chase G.

Reputation: 113

Instead you could use:

dungeonLayout = dungeonLayout + roomTypes[randint(0,4)]

This produces the "|T|C|M|T|M|C|C|C|C|" style output.

Upvotes: 0

user7669427
user7669427

Reputation:

Here you are!

from random import randint
roomTypes = ['T|', 'M|', 'W|', 'H|', 'C|']
dungeonList = []
dungeonLayout = ""
for i in range(1,10):
    dungeonList.append(roomTypes[randint(0, 4)])

dungeonLayout = dungeonLayout.join(dungeonList)
print(dungeonLayout)
print('Room types are Temple |T|, Abandoned Military Base |M|, Wizard\'s Abodes |W|, House |H|, Church |C|')
print('_____________________________')
print('|' + dungeonLayout)
print('_____________________________')

Because you were joining each time, the program was getting confused. Instead, I appended all the randoms into the list and then joined once. If you join the same thing many times over, the computer will begin to error

Upvotes: 0

sal
sal

Reputation: 3593

join is described here https://docs.python.org/2/library/stdtypes.html#str.join and in summary you use the str as the glue between each elements in a given iterable.

Since you want to basically create a list of "rooms", you could use a randomRooms list to store a list of random room types, and then use the join function just to save it out in the desired format. Note that you will have to still add a separator at the beginning and one at the end. Here the sample with minimal code diff to yours.

from random import randint
roomTypes = ['T', 'M', 'W', 'H', 'C']
randomRooms = []
for i in range(1,10):
    randomRooms.append(roomTypes[randint(0, 4)])
dungeonLayout = '|' + '|'.join(randomRooms) + '|'
print('Room types are Temple |T|, Abandoned Military Base |M|, Wizard\'s Abodes |W|, House |H|, Church |C|')
print('_____________________________')
print(dungeonLayout)
print('_____________________________')

Also on https://eval.in/750197

Upvotes: 2

Jan Böcker
Jan Böcker

Reputation: 190

Instead of

dungeonLayout = dungeonLayout.join(roomTypes[randint(0, 4)])

you probably meant

dungeonLayout += roomTypes[randint(0, 4)]

Your current code will pick a random two-character string from roomTypes, treat it as a sequence of letters, and join it using the dungeonLayout variable as a delimiter, so the resulting string will be someRoomType[0] + dungeonLayout + someRoomType[1].

You could also replace the complete 'for' loop with the following code, which expresses the idea of "take 10 random room types and join them together":

from random import choices dungeonLayout = ''.join(choices(roomTypes, k=10))

Upvotes: 0

Denziloe
Denziloe

Reputation: 8131

my_str.join takes a collection (i.e. an iterable) of strings and returns those strings glued together with my_str, e.g.

"x".join(["1", "2", "3"])
# "1x2x3"

and e.g.

"x".join("A|")
# Ax|

because A| is a collection of "A" and "|".

You could maybe fix the loop but it's better to use a comprehension:

"".join(roomTypes[randint(0,4)] for i in range(1,10))

Upvotes: 0

Related Questions