I know that my_str[1::3] gets me every 2nd character in chunks of 3, but what if I want to get every 2nd and 3rd character? Is there a neat way to do that with slicing, or do I need some other method like a list comprehension plus a join:
new_str = ''.join([s[i * 3 + 1: i * 3 + 3] for i in range(len(s) // 3)])
I think using a list comprehension with enumerate would be the cleanest.
>>> "".join(c if i % 3 in (1,2) else "" for (i, c) in enumerate("peasoup booze scaffold john"))
'eaou boz safol jhn'
Instead of getting only 2nd and 3rd characters, why not filter out the 1st items?
Something like this:
>>> str = '123456789'
>>> tmp = list(str)
>>> del tmp[::3]
>>> new_str = ''.join(tmp)
>>> new_str
'235689'
Related
I am creating a list of all versions of a string that can be made by deleting only one character using a comprehension. I am able to remove each character but not able to keep the other characters.
wrd = 'superstar'
list2 = [(wrd[:1-1] + wrd[:i+1]) for i in range(len(wrd))]
print(list2)
Your list slicing is a bit off. To remove a single character from a position in a string, use the form string[:index] + string[index + 1:] instead of string[:index - 1] + string[:index + 1]:
>>> word = 'superstar'
>>> words = [word[:i] + word[i + 1:] for i in range(len(word))]
>>> words
['uperstar', 'sperstar', 'suerstar', 'suprstar', 'supestar', 'supertar', 'supersar', 'superstr', 'supersta']
>>>
>>> from itertools import combinations
>>> wrd = 'superstar'
>>> [''.join(comb) for comb in combinations(wrd, len(wrd) - 1)]
['supersta', 'superstr', 'supersar', 'supertar', 'supestar', 'suprstar', 'suerstar', 'sperstar', 'uperstar']
Here's how to slice the 'wrd' superstar in a list comprehension:
wrd = 'superstar'
to remove each letter, you need to add the first part of the string to the second part that is leftover when you remove that character:
the first part of 'wrd' is everything up to i (your question has :1-1).
wrd[:i]
the second part of 'wrd' is everything from i+1 and onward to the end.
wrd[i+1:]
results:
list2 = [wrd[:i]+wrd[i+1:] for i in range(len(wrd))]
print(list2)
['uperstar', 'sperstar', 'suerstar', 'suprstar', 'supestar', 'supertar', 'supersar', 'superstr', 'supersta']
to delete more letters (like 2) at once in sequence, simply add to i in 'wrd':
list3 = [wrd[:i]+wrd[i+2:] for i in range(len(wrd))]
print(list3)
['perstar', 'serstar', 'surstar', 'supstar', 'supetar', 'superar', 'supersr', 'superst', 'supersta']
Hello I'm new to this programming language
I wanted to add the word 'and' before the last item in my list.
For example:
myList = [1,2,3,4]
If I print it the output must be like:
1,2,3 and 4
Here is one way, but I have to convert the int's to strings to use join:
myList = [1,2,3,4]
smyList = [str(n) for n in myList[:-1]]
print(",".join(smyList), 'and', myList[-1])
gives:
1,2,3 and 4
The -1 index to the list gives the last (rightmost) element.
This may not be the most elegant solution, but this is how I would tackle it.
define a formatter function as follows:
def format_list(mylist)
str = ''
for i in range(len(mylist)-1):
str.append(str(mylist[i-1]) + ', ')
str.append('and ' + str(mylist[-1]))
return str
then call it like this
>>> x = [1,2,3,4]
>>> format_list(x)
1, 2, 3, and 4
You can also use string formating:
l = [1,2,3,4]
print("{} and {}".format(",".join(str(i) for i in l[:-1]), l[-1]))
#'1,2,3 and 4'
Using join (to join list elements) and map(str,myList) to convert all integers inside list to strings
','.join(map(str,myList[:-1])) + ' and ' + str(myList[-1])
#'1,2,3 and 4'
Your question is misleading, if you are saying "How to add a word before the last word in list?" it means you want to add 'and' string before last item in the list , while many people are giving answer using .format() method , You should specify you want 'and' for printing or in list for further use of that result :
Here is list method according to your question :
myList = [1,2,3,4]
print(list((lambda x,y:(x+['and']+y))(myList[:-1],myList[-1:])))
output:
[1, 2, 3, 'and', 4]
Let say my string is as:
x = 'abcdefghi'
I want to reverse it in subsets of 3, so that my output is:
x = 'cbafedihg'
i.e. 0th index is swapped with 2nd index, 3rd index swapped with 5th, and so on.
Below is my code based on converting the string to list and swap the elements within the list:
string_list = list(x)
for i in range(len(string_list)/3):
string_list[i*3], string_list[i*3+2] = string_list[i*3+2], string_list[i*3]
''.join(string_list)
# Output: 'cbafedihg'
I want to know what will be the most efficient and most pythonic way to achieve it.
Note: len(x)%3 will always be 0.
The above code can be written using string slicing and list comprehension as:
# Here x[i*3:i*3+3][::-1] will reverse the substring of 3 chars
>>> ''.join([x[i*3:i*3+3][::-1] for i in range(len(x)/3)])
'cbafedihg'
Based on the comment by Delgan, it could be further simplified using step as 3 with range itself as:
>>> ''.join(x[i:i+3][::-1] for i in range(0, len(x), 3))
'cbafedihg'
Writing a function that is more readable and flexible?
def get_string(input_str, step=3):
output = ""
i = 0
for _ in list(input_str):
if i == len(input_str):
return output
elif i+step-1 >= len(input_str):
output += input[len(input_str)-1:i-1:-1]
return output
else:
output += input_str[i+step-1:i:-1] + input_str[i]
i += step
return output
And here comes the flexible part:
get_string("abcdefghi")
# Ouputs 'cbafedihg'
get_string("abcdefghi", 2)
# Outputs 'badcfehgi'
get_string("abcdefghi", 5)
# Outputs 'edcbaihgf'
Not to mention, if you want to add some more logic or change the logic, it is easier to change here.
Another alternative to achieve this is to type-cast your string to list, then simply swap the elements of list using list slicing with step as 3, and join back the list of strings as:
>>> string_list = list(x)
>>> string_list[::3], string_list[2::3] = string_list[2::3], string_list[::3]
>>> ''.join(string_list)
'cbafedihg'
I have a string which is very long. I would like to split this string into substrings 16 characters long, skipping one character every time (e.g. substring1=first 16 elements of the string, substring2 from element 18 to element 34 and so on) and list them.
I wrote the following code:
string="abcd..."
list=[]
for j in range(0,int(len(string)/17)-1):
list.append(string[int(j*17):int(j*17+16)])
But it returns:
list=[]
I can't figure out what is wrong with this code.
>>> string="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
Your original code, without masking the built-in (excludes the final full-length string and any partial string after it):
>>> l = []
>>> for j in range(0,int(len(string)/17)-1):
... l.append(string[int(j*17):int(j*17+16)])
...
>>> l
['abcdefghijklmnop', 'rstuvwxyzabcdefg', 'ijklmnopqrstuvwx']
A cleaned version that includes all possible strings:
>>> for j in range(0,len(string),17):
... l.append(string[j:j+16])
...
>>> l
['abcdefghijklmnop', 'rstuvwxyzabcdefg', 'ijklmnopqrstuvwx', 'zabcdefghijklmno', 'qrstuvwxyz']
How about we turn that last one into a comprehension? Everyone loves comprehensions.
>>> l = [string[j:j+16] for j in range(0,len(string),17)]
We can filter out strings that are too short if we want to:
>>> l = [string[j:j+16] for j in range(0,len(string),17) if len(string[j:j+16])>=16]
It does work -- but only for strings longer than 16 characters. You have
range(0,int(len(string)/17)-1)
but, for the string "abcd...", int(len(string)/17)-1) is -1. Add some logic to catch the < 16 chars case and you're good:
...
for j in range(0, max(1, int(len(string)/17)-1)):
...
Does this work?
>>> from string import ascii_lowercase
>>> s = ascii_lowercase * 2
>>> s
'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'
>>> spl = [s[i:i+16] for i in range(0, len(s), 17)]
>>> spl
['abcdefghijklmnop', 'rstuvwxyzabcdefg', 'ijklmnopqrstuvwx', 'z']
The following should work:
#!/usr/bin/python
string="abcdefghijklmnopqrstuvwxyz"
liszt=[]
leng=5
for j in range(0,len(string)/leng):
ibeg=j*(leng+1)
liszt.append(string[ibeg:ibeg+leng])
if ibeg+leng+1 < len(string):
liszt.append(string[ibeg+leng:])
print liszt
I have a list looking as follows
lst = ['.ab.cd.ef.gh.', '.ij.kl.mn.op.']
In each item, I want to replace item[0] with a * and item[-1] with a $.
I tried to use:
[item.eplace(item[0], '*') for item in lst]
but the result is that all . get replaced with * irrespective of position.
Appreciating your help!
This will work:
>>> lst = ['.ab.cd.ef.gh.', '.ij.kl.mn.op.']
>>> ['*' + item[1:-1] + '$' for item in lst]
['*ab.cd.ef.gh$', '*ij.kl.mn.op$']
>>>
item[1:-1], which uses Explain Python's slice notation, will get every character in item except for the first and the last:
>>> 'abcde'[1:-1]
'bcd'
>>> '*' + 'abcde'[1:-1] + '$' # Add the characters we want on each end
'*bcd$'
>>>
Use this code:
lst = ['.ab.cd.ef.gh.', '.ij.kl.mn.op.']
for k in range(0, len(lst)):
item = lst[k]
lst[k] = '*'+item[1:-1]+'$'
print lst
This loops over every item with a for loop and range(), and assigns lst[k] to item. Then it uses item[1:-1] to get the string excluding the first and last characters. Then we use string concatenation to add an asterisk to the beginning, and a dollar sign to the end. This runs as:
>>> lst = ['.ab.cd.ef.gh.', '.ij.kl.mn.op.']
>>> for k in range(0, len(lst)):
... item = lst[k]
... lst[k] = '*'+item[1:-1]+'$'
...
>>> print lst
['*ab.cd.ef.gh$', '*ij.kl.mn.op$']
>>>