0

I am trying to do something like this

x = 'no'
y = 'no'
z = 'no'

def xyz(arg):
    global x,y,z
    if foo in bar:
        if arg == 'no':
            print('yay')
            arg = 'yes'
        else:
            print('not yay')
    else:
        print('not yay')
        arg = 'no'

while True:
   xyz(x)
   xyz(y)
   xyz(z)

but it does not seem to change "arg" to yes or no. Any way I could do that?

5
  • 1
    Python does not have pass-by-reference semantics, assignment to an argument does not change anything outside of the function. Commented May 3, 2020 at 17:24
  • @bereal Actually Python does do pass-by-reference, but since arg is being reassigned, and since x, y, z are strings i.e. immutable, it's irrelevant. Commented May 3, 2020 at 17:53
  • Once you do arg = ... you simply bind the name arg in that scope to a new value. It will not affect arg's old value... Commented May 3, 2020 at 17:55
  • 1
    @wjandrea it's irrelevant whether they are immutable, if they are lists, the result will be the same. Passing by reference mean ability to access/assign values in the calling stack frame (void f(int &c) syntax in C++), which is not applicable to Python. Commented May 3, 2020 at 17:58
  • @bereal Oh OK, I misunderstood the terminology Commented May 3, 2020 at 18:00

3 Answers 3

1

i think your issue is that you're not returning your arg

like this:

def xyz(arg):
    global x,y,z
    if foo in bar:
        if arg == 'no':
            print('yay')
            arg = 'yes'
        else:
            print('not yay')
    else:
        print('not yay')
        arg = 'no'
    return arg

but you have to have a variable to write to after you have called the funtion,

example = xyz(arg)
Sign up to request clarification or add additional context in comments.

1 Comment

Get rid of global x,y,z. OP only used it because they misunderstood how it worked. What they were intending was basically x, y, z = map(xyz, [x, y, z]).
1

arg refers to a string object, e.g. 'no'. It cannot affect any other names that refer to the same string, e.g. x. It can't even change the value of the string object since strings are immutable.

What you should do is return from xyz and reassign x in the calling scope:

(Here I've also simplified the function logic and put the assignments onto one line to DRY them out.)

x = y = z = 'no'

def xyz(arg):
    if foo in bar and arg == 'no':
        print('yay')
        return 'yes'
    else:
        print('not yay')
        return 'no'

while True:
   x, y, z = map(xyz, [x, y, z])

Comments

0

I have implemented a working script. You should return the required value in the function and handling it on the caller side (when you call the function with the parameter).

The below script generates a random string and it returns "no" or "yes" based on if "a" is in the string (And prints your original "yay").

Code:

# Import modules for random string generation.
import random
import string

x = "no"
y = "no"
z = "no"


def generate_random_chars(number_of_chars):
    """
    Generating a random string.
    :param number_of_chars: Number of generated chars
    :return: The string with random chars.
    """
    return "".join(random.choice(string.ascii_letters) for _ in range(number_of_chars)).lower()


def xyz(arg):
    # Global variables are not needed. These are not used inside the function.
    # global x, y, z
    # Define the return value.
    return_value = "no"
    random_chars = generate_random_chars(10)
    print("Random characters: {}".format(random_chars))
    if "a" in random_chars:
        print("'a' is in generated chars")
        if arg == "no":
            print("yay")
            return_value = "yes"
        else:
            print("not yay")
    else:
        print("'a' is NOT in generated chars")
        print("not yay")
        # The following line is not needed because the default value of return in "no"
        # arg = "no"
    return return_value


# Only test in a 10th for loop Not in infinite while loop
for _ in range(10):
    print("X - Input: '{}' Output: '{}'".format(x, xyz(x)))
    print("Y - Input: '{}' Output: '{}'".format(y, xyz(y)))
    print("Z - Input: '{}' Output: '{}'".format(z, xyz(z)))

Output:

>>> python3 test.py 
Random characters: nbqrezimym
'a' is NOT in generated chars
not yay
X - Input: 'no' Output: 'no'
Random characters: ldbymrkarr
'a' is in generated chars
yay
Y - Input: 'no' Output: 'yes'
Random characters: cwlglelcqt
'a' is NOT in generated chars
not yay
Z - Input: 'no' Output: 'no'
Random characters: irjanpwnvh
'a' is in generated chars
yay
X - Input: 'no' Output: 'yes'
Random characters: rlvszdglqu
'a' is NOT in generated chars
not yay
Y - Input: 'no' Output: 'no'
Random characters: dnmvsjciwg
'a' is NOT in generated chars

Comments

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.