Without using reversed(), how would I loop a set of strings in Python in a function?
Stumbled upon ranges like:
range() and xrange() take a third parameter that specifies a step. So
you can do the following.
range(10, 0, -1) Which gives
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1] But for iteration, you should really
be using xrange instead. So,
xrange(10, 0, -1)
But these don't really speak to strings?
The function you're looking for is list comprehensions. These are useful in that you don't have to iterate over a sequence, which is what range and xrange (in 2.x) provide.
str can be iterated over and sliced, much like strings. The only difference is that str elements are immutable.
To your example, say you have a set of strings and you want to iterate over them. No problem - just remember that sets have no inherent ordering to them; they only guarantee that the contents are unique.
myset = set(["first", "second", "third", "fourth", "fifth"])
for i in myset:
print i
...which prints:
second
fifth
fourth
third
first
It's also the case that you can reverse a single string by itself using the step parameter for a sequence type, of which str belongs. You can do that with this:
"this is the song that never ends"[::-1]
...which prints:
'sdne reven taht gnos eht si siht'
try this:
>>> str = 'abcdefghijklmnopqrstuvwxyz'
>>> str[::-1]
'zyxwvutsrqponmlkjihgfedcba'
Related
I'm currently learning Python, and am starting to get confused by the use of letters, etc.
tup = [1,2,3,4,5]
for t in tup:
print(t)
Now, I could change 'tup' to 'mytuple' or 'my_list_of_numbers'.
Am I right in thinking that the next line is saying "call tup t and then we will just print t, instead of writing print tup"?
I'm struggling to understand the differences between people writing for X or for T or for Y in tup or mylist etc.
Any help appreciated.
The for in syntax is creating an iterator over the data structure.
So when you're using :
for x in iterable_object :
# Do something with x (ex : print(x))
x will take every value contained in iterable_object so in your example 1 then 2 then 3 then 4 then 5.
This syntax is equivalent to :
for i in range(len(iterable_object)) :
print(iterable_object[i])
# Do something with iterable_object[i]
It's a shortcut, like syntactic sugar.
For loop iterates through iterable objects.
The code block is executed for each member of the iterable, or sequence.
The actual syntax is:
for variable in sequence:
# code
In Python For doesn't require indexing variable inizialization, you just declare it in the statement.
In your example tup is your iterable object, and t is the variable in wich current element of the iterable is stored during iteration.
At first lets consider there no x, y or z just nothing in this
universe. You and I both know only Human Language.
Now lets look at two cases written in pure English language
case 1: Now if I give you a packet of buscuit and say:
open the packet and eat each buscuit one by one
case 2: and again give you a packet of buscuit and say:
for each buscuit in packet
eat it
desition: Both the cases are same by natural human expression.
Now lets say the same words in the language of Pythons
First we consider that there is an array named buscuit_packet
buscuit_packet = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
as pythons don't eat buscuits we are simply gonna print them
buscuit_packet = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for each in buscuit_packet:
print(each)
# here the word 'each' refers to one single buscuit we take and after using it
# we take the next one, it loops and the next one, it loops agian...
# until the last buscuit which is buscuit number 10 in our case and
# alas after eating buscuit no. 10 the loop terminates
# ps. a human will probably eat(each)
The output to this code will be:
12345678910
pure image output:
checkout the image of console output and feel the code
I know that the list() constructor creates a new list but what exactly are its characteristics?
What happens when you call list((1,2,3,4,[5,6,7,8],9))?
What happens when you call list([[[2,3,4]]])?
What happens when you call list([[1,2,3],[4,5,6]])?
From what I can tell, calling the constructor list removes the most outer braces (tuple or list) and replaces them with []. Is this true? What other nuances does list() have?
list() converts the iterable passed to it to a list. If the itertable is already a list then a shallow copy is returned, i.e only the outermost container is new rest of the objects are still the same.
>>> t = (1,2,3,4,[5,6,7,8],9)
>>> lst = list(t)
>>> lst[4] is t[4] #outermost container is now a list() but inner items are still same.
True
>>> lst1 = [[[2,3,4]]]
>>> id(lst1)
140270501696936
>>> lst2 = list(lst1)
>>> id(lst2)
140270478302096
>>> lst1[0] is lst2[0]
True
Python has a well-established documentation set for every release version, readable at https://docs.python.org/. The documentation for list() states that list() is merely a way of constructing a list object, of which these are the listed ways:
Using a pair of square brackets to denote the empty list: []
Using square brackets, separating items with commas: [a], [a, b, c]
Using a list comprehension: [x for x in iterable]
Using the type constructor: list() or list(iterable)
The list() function accepts any iterable as its argument, and the return value is a list object.
Further reading: https://docs.python.org/3.4/library/stdtypes.html#typesseq-list
Yes it is true.
Its very simple. list() takes an iterable object as input and adds its elements to a newly created list. Elements can be anything. It can also be an another list or an iterable object, and it will be added to the new list as it is.
i.e no nested processing will happen.
You said: "From what I can tell, calling the constructor list removes the most outer braces (tuple or list) and replaces them with []. Is this true?"
IMHO, this is not a good way to think about what list() does. True, square brackets [] are used to write a list literal, and are used when you tell a list to represent itself as a string, but ultimately, that's just notation. It's better to think of a Python list as a particular kind of container object with certain properties, eg it's ordered, indexable, iterable, mutable, etc.
Thinking of the list() constructor in terms of it performing a transformation on the kind of brackets of a tuple that you pass it is a bit like saying adding 3 to 6 turns the 6 upside down to make 9. It's true that a '9' glyph looks like a '6' glyph turned upside down, but that's got nothing to do with what happens on the arithmetic level, and it's not even true of all fonts.
aTuple = (123, 'xyz', 'zara', 'abc');
aList = list(aTuple)
print "List elements : ", aList
When we run above program, it produces following result:
List elements : [123, 'xyz', 'zara', 'abc']
It is another way to create a list in python. How convenient!
Your question is vague, but this is the output as follows, it doesn't "replace" the outer braces, it creates a data structure of a list, that can contain any value in a "listed" order (one after the other, after the other, and so on...) in a recursive way, you can add/remove elements to a specified index using append and pop. By the other hand, tuples are static and are not dynamically linked, they are more like an array of any type of element.
WHEN:
list((1,2,3,4,[5,6,7,8],9))
RETURNS:
[1, 2, 3, 4, [5, 6, 7, 8], 9]
WHEN:
list([[[2,3,4]]])
RETURNS:
[[[2, 3, 4]]]
WHEN:
list([[1,2,3],[4,5,6]])
RETURNS:
[[1, 2, 3], [4, 5, 6]]
Imagine the following function:
def getMinAndMax(numbers):
return min(numbers), max(numbers)
What will happen if I do this?
num = getMinAndMax([1,2,3,4,5])
Will num assume the value of the first item in the tuple, min, or will something else happen? I know I can just try it, but I'm looking for some defined Python behavior here.
Your function returns the two-element tuple min([1, 2, 3, 4, 5]), max([1, 2, 3, 4, 5]) which evaluates to 1, 5. So the statement
num = getMinAndMax([1,2,3,4,5])
will bind the name num to the tuple (1, 2) and you can access the individual values as num[0] and num[1]. Python does allow you, though, to use what's usually referred to as a unpacking assignment which looks like this:
nmin, nmax = getMinAndMax([1, 2, 3, 4, 5])
That binds each name to a succeeding element of the tuple on the right-hand side and allows you to use the values without indexing. If you need a tuple of the results your formulation is simplest, though of course the expression (nmin, nmax) will re-create it from the second one.
num will be a tuple. The value of num will be equal to (1,5) in your example. Python does not check types by default, so you can safely assign whatever value of whatever type you want to whatever variable.
According to the Python documentation, when I do range(0, 10) the output of this function is a list from 0 to 9 i.e. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. However the Python installation on my PC is not outputting this, despite many examples of this working online.
Here is my test code...
test_range_function = range(0, 10)
print(test_range_function)
print(type(test_range_function))
The output of this I'm thinking should be the list printed, and the type function should output it as a list. Instead I'm getting the following output...
c:\Programming>python range.py
range(0, 10)
<class 'range'>
I haven't seen this in any of the examples online and would really appreciate some light being shed on this.
That's because range and other functional-style methods, such as map, reduce, and filter, return iterators in Python 3. In Python 2 they returned lists.
What’s New In Python 3.0:
range() now behaves like xrange() used to behave, except it works with
values of arbitrary size. The latter no longer exists.
To convert an iterator to a list you can use the list function:
>>> list(range(5)) #you can use list()
[0, 1, 2, 3, 4]
Usually you do not need to materialize a range into an actual list but just want to iterate over it. So especially for larger ranges using an iterator saves memory.
For this reason range() in Python 3 returns an iterator instead (as xrange() did in Python 2). Use list(range(..)) if you want an actual list instead for some reason.
range() does not return an iterator, it is not iterator it is iterable. iterators protocol has 2 methods. __iter__ and __next__
r=range(10)
'__ iter __' in dir(r) # True
`__ next __` in dir(r) # False
iterable protocol requires __iter__ which returns an iterator.
r.__iter__()
# <range_iterator object at 0x7fae5865e030>
range() uses lazy eveluation. That means it does not precalculate and store range(10). its iterator, range_iterator, computes and returns elements one at a time. This is why when we print a range object we do not actually see the contents of the range because they don't exist yet!.
Is there any pre-made optimized tool/library in Python to cut/slice lists for values "less than" something?
Here's the issue: Let's say I have a list like:
a=[1,3,5,7,9]
and I want to delete all the numbers which are <= 6, so the resulting list would be
[7,9]
6 is not in the list, so I can't use the built-in index(6) method of the list. I can do things like:
#!/usr/bin/env python
a = [1, 3, 5, 7, 9]
cut=6
for i in range(len(a)-1, -2, -1):
if a[i] <= cut:
break
b = a[i+1:]
print "Cut list: %s" % b
which would be fairly quick method if the index to cut from is close to the end of the list, but which will be inefficient if the item is close to the beginning of the list (let's say, I want to delete all the items which are >2, there will be a lot of iterations).
I can also implement my own find method using binary search or such, but I was wondering if there's a more... wide-scope built in library to handle this type of things that I could reuse in other cases (for instance, if I need to delete all the number which are >=6).
Thank you in advance.
You can use the bisect module to perform a sorted search:
>>> import bisect
>>> a[bisect.bisect_left(a, 6):]
[7, 9]
bisect.bisect_left is what you are looking for, I guess.
If you just want to filter the list for all elements that fulfil a certain criterion, then the most straightforward way is to use the built-in filter function.
Here is an example:
a_list = [10,2,3,8,1,9]
# filter all elements smaller than 6:
filtered_list = filter(lambda x: x<6, a_list)
the filtered_list will contain:
[2, 3, 1]
Note: This method does not rely on the ordering of the list, so for very large lists it might be that a method optimised for ordered searching (as bisect) performs better in terms of speed.
Bisect left and right helper function
#!/usr/bin/env python3
import bisect
def get_slice(list_, left, right):
return list_[
bisect.bisect_left(list_, left):
bisect.bisect_left(list_, right)
]
assert get_slice([0, 1, 1, 3, 4, 4, 5, 6], 1, 5) == [1, 1, 3, 4, 4]
Tested in Ubuntu 16.04, Python 3.5.2.
Adding to Jon's answer, if you need to actually delete the elements less than 6 and want to keep the same reference to the list, rather than returning a new one.
del a[:bisect.bisect_right(a,6)]
You should note as well that bisect will only work on a sorted list.