0
import sys
input = sys.stdin.readline

n = int(input())
k = int(input())

cards = [input().rstrip() for _ in range(n)]

dp = [1] * n
res = set()
curStr = ""

def concat(cards, k, n, count):
    print(dp)
    print(curStr)

    if (count == k):
        res.add(curStr)
        return
    
    for i in range(n):
        if dp[i] == 0:
            curStr += cards[i]
            dp[i] = 1
        
            concat(cards,  k, n , count + 1)

            dp[i] = 0
            curStr = curStr[:-len(cards[i])] 


concat(cards, k, n, 0)
print(len(res))

in this code, i can access global variable "dp" without using "global dp" inside function concat, but i cannot do the same to global variable curStr.

so that "print(curStr)" gives me this error : UnboundLocalError: cannot access local variable 'curStr' where it is not associated with a value while print(dp) does not.

I thought I should say "global something" to use any type of global varaible inside function, but in this code, i think this principle is not applied, can you tell me what is the reason??

YSEO
  • 101
  • 7
  • 1
    What you say is simply not true. You can READ any global of any type within any function. But if you want to assign something NEW to a global name, you need a `global` statement. `dp[i] = 0` does not change which object is assigned to `dp`. `curStr += cards[i]` does change `curStr`, because strings cannot be modified. It has to assign a NEW OBJECT to `curStr`. That's the key to understanding the `global` statement. – Tim Roberts Mar 05 '23 at 02:12
  • 1
    There are multiple conceptual issues here. First off, "access" means many different things. The reason the function doesn't use the global `curStr` is because the assignment `curStr = curStr[:-len(cards[i])]` makes it **local and not global** in that function. That doesn't happen to `dp`, because there is no assignment - `dp[i] = ` is not assigning to `dp`, but instead modifying the object that is named. Separately, the reason you don't need `global dp` is, again, because you don't want to assign to it. – Karl Knechtel Mar 05 '23 at 02:15
  • @TimRoberts you are saying, READING, any global variable is okay within any function, but print(curStr) - this line inside function give UnboundLocalError, while print(dp) does not. I understand i need to say "global" to change global variable's value, but why just reading(print) it gives me error?? – YSEO Mar 05 '23 at 02:21
  • 1
    Once you assign a new object to `curStr` inside the function, Python changes its classification to "function local" for the ENTIRE FUNCTION. There is no longer any connection to the global variable. `dp[i]` does not assign a new object to `dp`, so it never gets reclassified. If you said `dp = []`, then the same thing would happen to `dp`. – Tim Roberts Mar 05 '23 at 02:29
  • @KarlKnechtel def concat(cards, k, n, count): dp = [1,2,3] after adding assiginment to "dp", it gives same error as curStr, now I understand assigining value to variable inside function. what I wonder is print(curStr) comes "before" curStr = curStr[:-len(cards[i])] , so I though at that print line, curStr is still global variable(which I can access without keyword "global"). since python interprets code from top to bottom, that "print(curStr)" should not throw error..isn't it?? sorry if i misunderstand – YSEO Mar 05 '23 at 02:31
  • " what I wonder is print(curStr) comes "before"" The order **does not matter**, and Python *does not "interpret" code* at all - the reference implementation is bytecode-compiled, just like Java and C# (and other .NET languages). Please read the linked duplicates, especially [my answer at the first linked duplicate](https://stackoverflow.com/a/73661023/523612). – Karl Knechtel Mar 05 '23 at 02:33
  • Python "compiles" the whole function to intermediate language before it executes anything. During that compile phase, if it sees you change a variable that was not mentioned in a `global`, it marks that variable as being "function local", and that marking applies as soon as it starts executing. It might not be intuitive, but that's the Python rule, and it does help prevent accidental naming collisions. – Tim Roberts Mar 05 '23 at 02:34
  • @TimRoberts Thanks for kind comment, i read your answer in link. Summarize my understanding: 1. Python is not an "interpreted" language, instead, it compiles python code before running 2. python determines variable scope "in process of compilation". And this process is like.. - global, nonlocal : name treated as global scope or first enclosing scope - if not, if there's "any sign of binding" like assignment in the code, name is local - if not, name refers to whichever first enclosing scope – YSEO Mar 05 '23 at 02:55
  • 1
    Well, the most common Python implementation is considered "interpreted". Like most interpreted languages, the code is converted to an "intermediate" language that's easier to scan, and then the interpreter goes through that intermediate language. – Tim Roberts Mar 05 '23 at 05:55

0 Answers0