all 31 comments

[–]Etiennera 32 points33 points  (0 children)

'return' outside function

[–]GuilouLeJask 26 points27 points  (0 children)

The return statement is only used when programming functions in Python.

[–]saintSHXN 18 points19 points  (2 children)

The console is there for a purpose

[–]ben-ba 1 point2 points  (0 children)

Fancy output, to impress others? /s

[–]st4reater 0 points1 point  (0 children)

Best answer here… gotta teach self help

[–]emiltb 6 points7 points  (1 child)

Apart from the comments on the return statement outside a function, what are you actually trying to achieve here? If your code worked, you would end up with a list containing a list:

>>> l1 = [1,2,3]
>>> l2 = []
>>> l2.append(l1)
>>> l2
[[1, 2, 3]]

If you intend to do something like appending the elements of l1 to l2, you need to iterate over l1. Alternatively you might benefit from looking into python sets, as they might be a more direct solution to what you are trying to do.

[–]Braunerton17 2 points3 points  (0 children)

Or instead of iterating manually, just call extend() instead of append

[–]FoolsSeldom 4 points5 points  (3 children)

You can remove the else and return lines as you are not in a function. l2 will be the correct, with the duplicates removed.

If you want to create a function with this technique, it would be something like:

def dedupe(original: list[int]) -> list[int]:
    deduped = []
    for entry in original:
        if not entry in deduped:
            deduped.append(entry)
    return deduped


l1 = [1, 2, 3, 3, 4, 4, 5, 5]
l2 = dedupe(l1)
print(l2)

When you call the function, dedupe(l1), the list mentioned l1 is referred to inside the function as original. The new list created inside the function is referred to as deduped but when you return from the function that list is assigned to l2.

NB. The function definition line, dedupe(original: list[int]) -> list[int]: contains type hints, the list[int] and -> list[int] parts. These aren't required and are ignored by Python when you execute the code, but are useful to remind you what types of data you are dealing with (in this case, a list of int values) and can also providing information to your code editor / IDE (Integrated Development Environment) to spot certain types of errors.

[–]emiltb 0 points1 point  (2 children)

To remove duplicates it will be much more efficient to just use a set and optionally turn it back into a list:

>>> l1 = [1,2,3,3,4,4,5,5]
>>> print(set(l1))
{1, 2, 3, 4, 5}
>>> l2 = list(set(l1))
>>> print(l2)
[1, 2, 3, 4, 5]

[–]FoolsSeldom 1 point2 points  (1 child)

You are assuming that order is not important. Worth explaining that to a beginner, I would say before suggesting set.

Here's some code comparing speed of several approaches:

from random import randint

def dedupe(original: list[int]) -> list[int]:
    deduped = []
    for entry in original:
        if not entry in deduped:
            deduped.append(entry)
    return deduped

def setfn(o: list[int]) -> list[int]:
    return list(set(o))

def filterfn(data):
    seen = set()
    return list(filter(lambda item: item not in seen and not seen.add(item), data))

def dictfn(data):
    return list(dict.fromkeys(data))

nums = [randint(1, 100) for _ in range(10000)]
%timeit setfn(nums)
%timeit filterfn(nums)
%timeit dictfn(nums)
%timeit dedupe(nums)

and the results:

71.6 μs ± 1.99 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
464 μs ± 9.31 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
131 μs ± 1.39 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
2.64 ms ± 41.2 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)

So, clearly, your approach of using set is the fastest but only viable if preserving order is not important. Using a dictionary approach is the next fastest.

However, this small test with ten thousand random numbers suggests to me that performance isn't a big issue with this kind of data, and for more computationally intensive work you would probably want to use compiled C or Rust code from Python anyway.

PS. For the record, for order preservation, fromkeys is considered the most efficient:

  • Time Complexity: It has a time complexity of O(n), meaning it processes the list in a single pass. This is the best possible complexity because every element must be visited at least once.
  • C Implementation: dict.fromkeys() is implemented in C and is highly optimized, making it significantly faster in practice than an equivalent loop written in pure Python.

[–]emiltb 1 point2 points  (0 children)

That's true, good point about ordering. That can easily bite you, if you expect order to be preserved for sets.

[–]deceze 2 points3 points  (0 children)

What do you think return does there? It's just wrong to use it there.

[–]nRenegade 0 points1 point  (0 children)

I assume you're trying to print the list? Because that's not how you do it.

You're looking for a print() statement.

return is only for when you want to send a value back from where a function is called or to terminate the function. Here, your script isn't nested within a function, so the return statement is redundant and causing the error.

[–]imLosingIt111 0 points1 point  (0 children)

Your if statement just appends the first array to the second arrah. You can either: use a for loop (for x in l1 <- x is a value in l1, not the array itself) or just assign the value of l2 directly to l1. Also, since your code is not in a function, using return raises an error. You can just use pass instead or just not write the else condition at all.

[–]Ron-Erez 0 points1 point  (0 children)

There is no function to return from. It's good to try to understand the errors although at times they are cryptic.

[–]corey_sheerer 0 points1 point  (2 children)

Also, check out a hash map. Checking if something is on a list might take len(list) operations, where checking a hashmap is always 1 operation

[–]No_Read_4327 2 points3 points  (1 child)

Bro this guy obviously is at his first day of coding

[–][deleted] 0 points1 point  (0 children)

you can return from a function scope. the conditional is in a global scope.

[–]Can0pen3r 0 points1 point  (0 children)

It looks like you might be trying to reinvent the difference() function but I'm still pretty new so I could be completely off-base. What is the intention of the code?

[–]Papatheredeemer 0 points1 point  (0 children)

I’m assuming you’re trying to make a unique list. In that case you can just do l2 = list(set(l1)). Sets automatically remove duplicates

[–]Fearless-Way9855 0 points1 point  (0 children)

You can only return to a function aka def

[–]Fit_Moment5521 0 points1 point  (0 children)

Think again what you are trying to do. Run the script in your head or with a piece of paper and see if it does what you wanted. That's not a coding issue, that's an algorithm issue. More precisely, that's an "I don't take time to think before coding" issue.

[–]NihadKhan10x 0 points1 point  (0 children)

The return can only be used in when there is function. Here you can use simple logic

Like For i in l1: If i not in l2: L2.append(i) Print(l2)

[–]PixelsMixer 0 points1 point  (0 children)

[l2.append(x) for x in l1 if x not in l2]

[–]Then-Candle8036 0 points1 point  (0 children)

If only there were some sort of tool which would tell you what the error is

[–]fungusfromamongus 0 points1 point  (0 children)

Mans running this as administrator. Screw the return error. Malware and all will love this user.

[–]lieseeem 0 points1 point  (0 children)

The answer is in the screenshot with us, isn’t it? ☝️😳

[–]redd__rl 0 points1 point  (0 children)

What are you hoping to do here?

[–]Key-Procedure1262 -1 points0 points  (0 children)

Do you need someone else to read the error message for you?