This question already has answers here:
What does it mean when the parentheses are omitted from a function or method call?
(6 answers)
Closed 2 years ago.
In Python, there are functions that need parentheses and some that don't, e.g. consider the following example:
a = numpy.arange(10)
print(a.size)
print(a.var())
Why does the size function not need to be written with parentheses, as opposed to the variance function? Is there a general scheme behind this or do you just have to memorize it for every function?
Also, there are functions that are written before the argument (as opposed to the examples above), like
a = numpy.arange(10)
print(np.round_(a))
Why not write a.round_ or a.round_()?
It sounds like you're confused with 3 distinct concepts, which are not specific to python, rather to (object oriented) programming.
attributes are values, characteristics of an object. Like array.shape
methods are functions an object can run, actions it can perform. array.mean()
static methods are functions which are inherent to a class of objects, but don't need an object to be executed like np.round_()
It sounds like you should look into OOP: here is a python primer on methods.
Also, a more pythonic and specific kind of attributes are propertys. They are methods (of an object) which are not called with (). Sounds a bit weird but can be useful; look into it.
arrange returns an ndarray. size isn't a function, it's just an attribute of the ndarray class. Since it's just a value, not a callable, it doesn't take parenthesis.
Related
So .loc and .iloc are not your typical functions. They somehow use [ and ] to surround the arguments so that it is comparable to normal array indexing. However, I have never seen this in another library (that I can think of, maybe numpy as something like this that I'm blanking on), and I have no idea how it technically works/is defined in the python code.
Are the brackets in this case just syntactic sugar for a function call? If so, how then would one make an arbitrary function use brackets instead of parenthesis? Otherwise, what is special about their use/defintion Pandas?
Note: The first part of this answer is a direct adaptation of my answer to this other question, that was answered before this question was reopened. I expand on the "why" in the second part.
So .loc and .iloc are not your typical functions
Indeed, they are not functions at all. I'll make examples with loc, iloc is analogous (it uses different internal classes).
The simplest way to check what loc actually is, is:
import pandas as pd
df = pd.DataFrame()
print(df.loc.__class__)
which prints
<class 'pandas.core.indexing._LocIndexer'>
this tells us that df.loc is an instance of a _LocIndexer class. The syntax loc[] derives from the fact that _LocIndexer defines __getitem__ and __setitem__*, which are the methods python calls whenever you use the square brackets syntax.
So yes, brackets are, technically, syntactic sugar for some function call, just not the function you thought it was (there are of course many reasons why python is designed this way, I won't go in the details here because 1) I am not sufficiently expert to provide an exhaustive answer and 2) there are a lot of better resources on the web about this topic).
*Technically, it's its base class _LocationIndexer that defines those methods, I'm simplifying a bit here
Why does Pandas use square brackets with .loc and .iloc?
I'm entering speculation area here, because I couldn't find any document explicitly talking about design choices in Pandas, however: there are at least two good reasons I see for choosing the square brackets.
The first, and most important reason is: you simply can't do with a function call everything you do with the square-bracket notation, because assigning to a function call is a syntax error in python:
# contrived example to show this can't work
a = []
def f():
global a
return a
f().append(1) # OK
f() = dict() # SyntaxError: cannot assign to function call
Using round brackets for a "function" call, calls the underlying __call__ method (note that any class that defines __call__ is callable, so "function" call is an incorrect term because python doesn't care whether something is a function or just behaves like one).
Using square brackets, instead, alternatively calls __getitem__ or __setitem__ depending on when the call happens (__setitem__ if it's on the left of an assignment operator, __getitem__ in any other case). There is no way to mimic this behaviour with a function call, you'd need a setter method to modify the data in the dataframe, but it still wouldn't be allowed in an assignment operation:
# imaginary method-based alternative to the square bracket notation:
my_data = df.get_loc(my_index)
df.set_loc(my_index, my_data*2)
This example brings me to the second reason: consistency. You can access elements of a DataFrame via square brackets:
something = df['a']
df['b'] = 2*something
when using loc you're still trying to refer to some items in the DataFrame, so it's more consistent to use the same syntax instead of asking the user to use some getter and setter functions (it's also, I believe, "more pythonic", but that's a fuzzy concept I'd rather stay away from).
Underneath the covers, both are using the __setitem__ and __getitem__ functions.
This question already has answers here:
Difference between len() and .__len__()?
(5 answers)
Closed 7 years ago.
I have two examples:
a = [1,2,3]
b = 4
print (a.__len__())
print (len(a))
print(b.__add__(4))
print (b + 4)
I guess my question is, is there a difference when using __len__ magic method versus the built in len() method? The only time I see people use __len__ is when trying to trying to find the length of an object of a user-created class.
Same with other dunder methods, such as __str__, or __add__ I never seem them used outside of a class or OOP in general.
There are only small differencies. Function is just a function, that call len. Something like
def len(x):
return x.__len__()
Of course, you can override builtin len, but that is dump (maybe except debugging). Only different thing is len(x) is easier to read, and x.__len__ allows you create your own implentation of operator. x.__len__ also can be bit faster, but it is a good reason to use it.
When operator have 2 arguments its implementation do more. a+b at first it tries, whether is callable a.__add__ and if it is not, than tries to call b.__radd__.
This question already has answers here:
What's the difference between a method and a function?
(41 answers)
Closed 7 years ago.
I am a little confused about functions in Python, and how they are classified. For one, we have functions like print(), that simply encode some instructions and act on input. But also, we have functions like 'str'.capitalize(), that can only act when they have an "executor" attached to them. This might not be a well-informed question, but what are the differences between these forms, and how are they classified?
print() is a function in python3 (in python2 it was a statement), and capitalize() is a method.
Please take a look at this answer to clear things up a little bit.
Python is a multi paradigm language that you can write structural and object oriented. Python has built-in functions and built-in classes; for example when you use sequence of characters between two quotation mark (') you instantiate string class.This instance called object. Objects may contain functions or/and other objects. you can access internal functions or object with DOT.
Python is object oriented. This means we have "objects", which basically enclose their own data, and have their own methods. a String is an example of an object. Another example would be if you have a Person object. You can't just do walk(), you have to do Miles.walk(). You could try walk(Miles). But not everything can walk, so we make the function walk() specific to Person objects.
So yes, Python creators could have made capitalize('str') legal, but they decided to make the capitalize function specific to String objects.
print() is a built in function, you can check that like below..
>>> type(print)
<class 'builtin_function_or_method'>
>>> hasattr(print, '__call__')
True
But capitalize() is method of a str class, you can only use this by using string objects.
>>> hasattr('string', 'capitalize')
True
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python: How do I pass a variable by reference?
I'm trying to write a function that modifies one of the passed parameters. Here's the current code:
def improve_guess(guess, num):
return (guess + (num/guess)) / 2
x = 4.0
guess = 2.0
guess = improve_guess(guess, x)
However, I want to write the code in such a way that I don't have to do the final assignment. That way, I can just call:
improve_guess(guess,x)
and get the new value in guess.
(I intentionally didn't mention passing-by-reference because during my net-searching, I found a lot of academic discussion about the topic but no clean way of doing this. I don't really want to use globals or encapsulation in a list for this.)
You can't do this directly since integer and floating-point types are immutable in Python.
You could wrap guess into a mutable structure of some sort (e.g. a list or a custom class), but that would get very ugly very quickly.
P.S. I personally really like the explicit nature of guess = improve_guess(guess, x) since it leaves no doubt as to what exactly is being modified. I don't even need to know anything about improve_guess() to figure that out.
But those are the only two ways to do it: either use a global, or use a mutable type like a list. You can't modify a non-mutable variable in Python: doing so just rebinds the local name to a new value.
If you really don't like wrapping in a list, you could create your own class and pass around an instance that will be mutable, but I can't see any benefit in doing that.
This question already has answers here:
How do I get the number of elements in a list (length of a list) in Python?
(11 answers)
Closed 13 days ago.
The community is reviewing whether to reopen this question as of 8 days ago.
In Python, is the following the only way to get the number of elements?
arr.__len__()
If so, why the strange syntax?
my_list = [1,2,3,4,5]
len(my_list)
# 5
The same works for tuples:
my_tuple = (1,2,3,4,5)
len(my_tuple)
# 5
And strings, which are really just arrays of characters:
my_string = 'hello world'
len(my_string)
# 11
It was intentionally done this way so that lists, tuples and other container types or iterables didn't all need to explicitly implement a public .length() method, instead you can just check the len() of anything that implements the 'magic' __len__() method.
Sure, this may seem redundant, but length checking implementations can vary considerably, even within the same language. It's not uncommon to see one collection type use a .length() method while another type uses a .length property, while yet another uses .count(). Having a language-level keyword unifies the entry point for all these types. So even objects you may not consider to be lists of elements could still be length-checked. This includes strings, queues, trees, etc.
The functional nature of len() also lends itself well to functional styles of programming.
lengths = map(len, list_of_containers)
The way you take a length of anything for which that makes sense (a list, dictionary, tuple, string, ...) is to call len on it.
l = [1,2,3,4]
s = 'abcde'
len(l) #returns 4
len(s) #returns 5
The reason for the "strange" syntax is that internally python translates len(object) into object.__len__(). This applies to any object. So, if you are defining some class and it makes sense for it to have a length, just define a __len__() method on it and then one can call len on those instances.
Just use len(arr):
>>> import array
>>> arr = array.array('i')
>>> arr.append('2')
>>> arr.__len__()
1
>>> len(arr)
1
Python uses duck typing: it doesn't care about what an object is, as long as it has the appropriate interface for the situation at hand. When you call the built-in function len() on an object, you are actually calling its internal __len__ method. A custom object can implement this interface and len() will return the answer, even if the object is not conceptually a sequence.
For a complete list of interfaces, have a look here: http://docs.python.org/reference/datamodel.html#basic-customization
The preferred way to get the length of any python object is to pass it as an argument to the len function. Internally, python will then try to call the special __len__ method of the object that was passed.
you can use len(arr)
as suggested in previous answers to get the length of the array. In case you want the dimensions of a 2D array you could use arr.shape returns height and width
len(list_name) function takes list as a parameter and it calls list's __len__() function.
Python suggests users use len() instead of __len__() for consistency, just like other guys said. However, There're some other benefits:
For some built-in types like list, str, bytearray and so on, the Cython implementation of len() takes a shortcut. It directly returns the ob_size in a C structure, which is faster than calling __len__().
If you are interested in such details, you could read the book called "Fluent Python" by Luciano Ramalho. There're many interesting details in it, and may help you understand Python more deeply.