Smuugl
Smuugl

Reputation: 11

Going through a list and replacing a string in Python

I'm new to python and want to create a simple inventory function for my text based game. I want the function to go through the list (inventory) and replace the first line titled "empty" with an item.

Heres what I have:

Inventory =["Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty"]

def inventory(item):
    for line in Inventory:

It's not much I know. So basically when I enter an "item" into the function, I want the function to go through the list, find the first "Empty" string and replace it with the "item", then stop. Hope this isn't too vage of a question.

Upvotes: 0

Views: 89

Answers (4)

CrazyPythonProgrammer
CrazyPythonProgrammer

Reputation: 1317

here is the code it is assuming that there is at least one "Empty" string in Inventory

Inventory = ["Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty"]
def inventory(item):
    Inventory[Inventory.index("Empty")] = item

Without assuming

Inventory = ["Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty"]
def inventory(item):
    try:
        Inventory[Inventory.index("Empty")] = item
    except ValueError:
        pass # since you didn't mention what to do if "Empty" does not exist

Upvotes: 0

Michael Hsi
Michael Hsi

Reputation: 439

I think it's best if you modify the list without passing it into a no-return function. This involves python mutable variable, reference and scope.

Essentially, you might think a list can be passed into a function and have its values changed within the function, but it should remain unchanged outside the function. However that's not how python list works.

For example:

def temp(data):
    data.clear()

data1 = [1,2,3]
temp(data1)
print(data1) 

# output:
[] 

The short version is that python variables are refered by their id, and passing a list as-is (just passing the name, as example show) into a function means that now list inside the function and outside the function shares same id, which means modification done within the function will affect list outside the function. (same behavior when you pass a list into multiple different function, now every function is modifying that list)

Also, depending on how you modify the list, sometimes a new id can be generated, which can mess up the logic even more.

I think the best way is to pass a copy of the original list (so that function uses a list with same value but different id, meaning all modification will not reflect to the original list), and have the function return the new list. Then assign the new return to your variable

ps. passing a copy of a list means that you're duplicating value and taking more memory, but it's really not that significant unless you have a 1GB list. If so, passing it in without .copy() and use new value from function return also works.

def process_list(data):
    # code provided by other answers 
    return data 

inventory = process_list(inventory.copy())

This way it's more clear about how the value are being changed

Upvotes: 1

gnahum
gnahum

Reputation: 436

To do this you can say:

Inventory = ["Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty", "Empty"]
def inventory(item): 
   for i in range(len(Inventory)): 
       if Inventory[i] == 'Empty': 
          Inventory[i] = item 
          break; 

Alternatively you can do this in one line and say:

def inventory(item): 
    if 'Empty' in Inventory: 
       firstEmptyIndex = Inventory.index('Empty')
       Inventory[firstEmptyIndex]  = item 

Upvotes: 1

Błotosmętek
Błotosmętek

Reputation: 12927

There's no need to use a loop for that.

try:
    empty_pos = Inventory.index("Empty")
except ValueError:
    print("No empty slots!")
else: 
    Inventory[empty_pos] = item

Upvotes: 1

Related Questions