Python range of a list? - python

I'd like to be able to get a range fields of a list.
Consider this:
list = ['this', 'that', 'more']
print(list[0-1])
where the [0-1] should return the first and second fields.

You will want to use Python's slice notation for this:
>>> lst = ['this', 'that', 'more']
>>> print(lst[:2])
['this', 'that']
>>>
The format for slice notation is [start:stop:step].
Also, I changed the name of the list to lst. It is considered a bad practice to name a variable list since doing so overshadows the built-in.

use:
list = ['this', 'that', 'more']
print(list[0:2])

Related

Python: How to concatenate adjacent strings in list having combined length less than threshold?

I would like to merge/concatenate adjacent strings in a list whose combined length is below a threshold. The concatenated string should have a single space separating the individual strings.
For example, if the list contains the following strings:
list = ['This', 'is', 'a', 'sample', 'example']
and the threshold is 10, then the list should be modified to:
list = ['This is a', 'sample', 'example']
Edit: I am using a for loop comparing adjacent strings.
for i in range(1, len(list)):
if len(list[i]) + len(list[i-1]) < 10:
list[i-1] = list[i-1]+' '+list[i]
del list[i]
but this gives IndexError: list index out of range because the loop counter has been initialized to the initial len(list).
One (a bit lazy) way to do this is using the textwrap module from the standard library:
>> import textwrap
>> textwrap.wrap('This is a sample example', width=10)
['This is a', 'sample', 'example']
(If your text is already split into words, you'll have to join it back first, which is a bit wasteful, but still works.)
import re
import textwrap
sample = ['This', 'is', 'a', 'sample', 'example', 'stringbiggerthan10', 'otherstring']
sample_join = " ".join(sample)
textwrap.wrap(sample_join, width=10, break_long_words=False)
['This is a', 'sample', 'example', 'stringbiggerthan10', 'otherstring']

Splitting a single index list into multiple list indexes?

I have a list:
lst = ['words in a list']
and I was hoping to split each one of these words in the string into their own separate indexes. So for example, it would look something like this:
lst = ['words','in','a','list']
I'm wondering if this is possible? I thought initially this would be just a simple lst.split() with a loop, but it seems like this is will throw an error.
Thanks for the help!
Use this:
print(lst[0].split())
If the list has more elements:
print([x for i in lst for x in i.split()])
Split only works for a string type. So you need to index the list item first and then split.
lst = lst[0].split()
Use this when you have a list of string or single string inside a list
lst = ['this is string1', 'this is string2', 'this is string3']
result =' '.join(lst).split()
print(result)
# output : ['this', 'is', 'string1', 'this', 'is', 'string2', 'this', 'is', 'string3']

I get the correct output only when I add another return value in Python3.x

Sorry for the unspecific title, but I was not able to explain it better.
I have this python code:
def longestWord_with_recursion(wrds):
if type(wrds) == str:
return len(wrds),wrds
return max([longestWord_with_recursion(x) for x in wrds])
(...)
words = [list of words]
print(longestWord_with_recursion(words))
The return with len(wrds),wrds gives me the following:
(11, 'programming') #programming is the correct answer
However, since I only want to return the word, I replace the return with return wrds, which gives me the following:
you #another word in the list, but the wrong one
Why does this happen? Why does it give me the correct word if I add another return value but not if I only return this one? And how could one fix this?
E: The list of words is:
['The', 'Scandal', 'of', 'education', 'is', 'that', 'every', 'time', 'you', 'teach', 'something', 'you', 'deprive', 'a', 'student', 'of', 'the', 'pleasure', 'and', 'benefit', 'of', 'discovery', 'Seymour', 'Papert', 'born', 'February', '29', '1928', 'died', 'July', '31', '2016', 'If', 'debugging', 'is', 'the', 'process', 'of', 'removing', 'bugs', 'then', 'programming', 'must', 'be', 'the', 'process', 'of', 'putting', 'them', 'in', 'Edsger', 'W', 'Dijkstra']
When you return only the word, the list you form with your recursion statement is merely the list of words. "you" is the greatest word (last one alphabetically) in the list. You must return the length to have the previous call level operate on that data.
Please note that this isn't recursion in any but the syntactic sense. Your function has two disparate operations that don't really interact: if it's called with a string, it does one thing; if it's called with any other data type, it iterates. This is not really "base case" and "recursion case", unless you have nested lists of words.
This does not seem like proper use of recursion. It looks more like you're trying to overload the longestWord_with_recursion function with two functionalities:
Change a list of words into a list of tuples with (word_length, word) and
Return the largest word based on the list of tuples.
You could rewrite the entire function into:
def longest_word(iterable):
return max([(len(x), x) for x in iterable])
which will return the longest word as well, while still using the built-in max function. This will return a tuple of (word_length, word), so if you only want the word returned, you can do:
def longest_word(iterable):
return max([(len(x), x) for x in iterable])[1]
Notice the [1] at the end.
Edit:
Looking at the documentation of max some more, as well as the comment by #Kenny in the comments, it can be made even simpler with:
def longest_word(iterable):
return max(iterable, key=len)
At this point, is it really worth being its own function?
Try this:
def longestWord_with_recursion(wrds):
if type(wrds) == str:
return len(wrds),wrds
return max([longestWord_with_recursion(x) for x in wrds])[1]
print(longestWord_with_recursion(words))
It's returning a list of two elements, so you just have to indicate that the element you wanna print is the second one!

Most efficient way to find the indexes of unique values in a Python 3 list

What is the most efficient way to find the indexes of strings in a list that occur only once?
foo = ['it', 'does', 'it', 'very', 'very', 'well']
bar = ??? # bar = [1, 5]
I already know about sets, dictionaries and list comprehensions. The problem I'm trying to solve here is in my production code I have parallel data lists where the index of one is the index of many which can't be changed for historical reasons.
With collections.Counter subclass:
import collections
foo = ['it', 'does', 'it', 'very', 'very', 'well']
counts = collections.Counter(foo)
result = [i for i,v in enumerate(foo) if counts[v] == 1]
print(result)
The output:
[1, 5]
You will get what you want. Dictionaries are faster in python
from collections import Counter
foo = ['it', 'does', 'it', 'very', 'very', 'well']
d = dict(Counter(foo))
[i for i,v in enumerate(foo) if counts[v] == 1]
You can also use set(foo)
You can try something like this, especially if the size of your foo list is bigger than in your example above and have lots of duplicates.
seen = set()
[i for i,e in enumerate(foo) if not (e in seen or seen.add(e) or e in foo[i+1:])]
It depends on the kind of efficiency you would like to get. You could do this directly in a list comprehension, straightforward and readable:
bar = [index for index,el in enumerate(foo) if foo.count(el)==1]
Please see this for info if you would like to use Counter

sort list of lists by specific index of inner list

I am trying perform some operation on a file and convert its lines to list. However the integer values are also taken as string
l1 = [['test', 'hello', '60,'], ['why', 'to', '500,'], ['my', 'choice', '20,']]
because of this I am unable to sort the list of list based on these integer values.
Is there a way I can convert all these list[2] values into integer and sort the outer list based on that? Or any other way via which I can sort this list using integers in above list.
Intended result is, output of sorted list should show as:
[['my', 'choice', '20,'], ['test', 'hello', '60,'], ['why', 'to', '500,']]
Use a custom sort key, to convert the last element to an integer just when sorting:
sorted(l1, key=lambda l: int(l[2].rstrip(',')))
The key is used to produce the value on which to sort, for each element in the list. So the lambda function is called for each element, and the above code extracts the l[2] value, converting it to an integer. The str.rstrip() call removes the trailing comma first.
Demo:
>>> l1 = [['test', 'hello', '60,'], ['why', 'to', '500,'], ['my', 'choice', '20,']]
>>> sorted(l1, key=lambda l: int(l[2].rstrip(',')))
[['my', 'choice', '20,'], ['test', 'hello', '60,'], ['why', 'to', '500,']]

Categories