def split(word):
return [char for char in word]
a = "8hypotheticall024y6wxz"
alp = "ABCDEFGHIKLMNOPQRSTVXYZ"
alph = alp.lower()
b= split(alph)
c = set(b)-set(a)
c = sorted(c)
c = str(c)
res = [int(i) for i in a if i.isdigit()]
num_list = [0,1,2,3,4,5,6,7,8,9]
l = set(num_list)-set(res)
l = sorted(l)
l = str(l)
print(l,c)
The output I get is
[1, 3, 5, 7, 9] ['b', 'd', 'f', 'g', 'k', 'm', 'n', 'q', 'r', 's', 'v']
The output I want is
"13579bdfgjkmnqrsuv"
How do I get it?
Please provide me with the code to get rid of these square brackets, commas and quotation marks.
Add this is in the last -
l.extend(c)
l = [str(i) for i in l]
print(''.join(l)) # 13579bdfgkmnqrsv
Additionally, you could simplify your code (No need of function and many reassignments) -
a = "8hypotheticall024y6wxz"
alp = "ABCDEFGHIKLMNOPQRSTVXYZ"
b = alp.lower()
c = sorted(set(b)-set(a))
res = [int(i) for i in a if i.isdigit()]
num_list = [0,1,2,3,4,5,6,7,8,9]
l = sorted(set(num_list)-set(res))
l.extend(c)
l = [str(i) for i in l]
print(''.join(l))
I guess you can make another string like this
str = ""
for i in [your output list]:
str += i
For the list c, which is a list of strings, you can convert it with ''.join(c) instead of str(c).
For the list l, you can do the same thing but you have to convert every element to a string. One concise way to do this is with, map(str, l). To accomplish the conversion in one line, you could to ''.join(map(str,l))
Related
Hello guys I'm trying to create a function that returns a list out of a string ((((Without the space))))
I'm using the replace function to remove the space however I'm still getting a space
def str2list(argstr):
retlist = []
for c in argstr:
c=c.replace(" ", "")
retlist.append(c)
return retlist
print(str2list('abc efg'))
output: ['a', 'b', 'c', '', 'e', 'f', 'g']
desired output: ['a', 'b', 'c', 'e', 'f', 'g']
A simple list comprehension should suffice:
def str2list(argstr):
return [c for c in argstr if c != ' ']
You are replacing spaces with empty strings, where you would like to remove them from the list entirely. Think about what happens when the loop sees " ".
The simple fix is instead to not append spaces.
def str2list(argstr):
retlist = []
for c in argstr:
if c != " ":
retlist.append(c)
return retlist
print(str2list('abc efg'))
Somewhat more elegantly, try
def str2list(argstr):
return [c for c in argstr if c != " "]
(Thanks to #Cobra for the improved implementation; I had a clumsy lambda at first.)
If you are open to using regex, you may try:
inp = "abc efg"
letters = re.findall(r'[a-z]', inp, flags=re.I)
print(letters) # ['a', 'b', 'c', 'e', 'f', 'g']
You could also use:
inp = "abc efg"
output = list(inp.replace(" ", ""))
print(output) # ['a', 'b', 'c', 'e', 'f', 'g']
A very clean solution, without using libraries or replacements, is using List Comprehension.
The syntax of this tool is as follows:
[expression for item in iterable if condition == True]
so the code becomes:
def str2list(argstr):
return [x for x in argstr if x != " "]
is the same thing, in a more compact way than the similar function you wrote, with an extra if statement:
def str2list(argstr):
retlist = []
for c in argstr:
if c != " ":
retlist.append(c)
return retlist
The easiest is to check if a character is a place
if c == ' '
or see if it a character is not
c != ' '
then you don't need to replace it. You're just changing a ' ' to a '' then adding it. you need to exclude it
def str2list(argstr):
retlist = []
for c in argstr:
if c != " ":
retlist.append(c)
return retlist
This will fix your issue.
Or you could just use a comprehension
def str2list():
return [c for c in argstr if c != ' ']
I have the following string
"long"
And I have an array of chars that will contain the sequence [..., [l],[o],[n],[g],...] somewhere in it. Can someone help me find a way to compare the string to the array of chars and return a True or False without having to join the array into one string?
Thanks!
I won't claim you should do it this way, but you certainly could.
z = "long"
a = [letter for letter in z]
b = ['l', ' ', 'x', 4, 'l', 'o', 'n', 'g', 5]
for i, j in enumerate(b):
if a == b[i:i+len(a)]:
print('"{}" found at index {}'.format(z,i))
Effectively we explode the string and then create slices of the list for comparison to the exploded string.
You can do this:
s = 'long'
lst = [['a'],['l'],['o'],['n'],['g'],['z']]
p = [[x] for x in s]
any([p==lst[i:i+len(p)] for i in range(0, len(lst)-len(p))])
Out[81]: True
Question in comment: "How to get the index of first match?"
[j for j, i in enumerate(range(0, len(lst)-len(p))) if p==lst[i:i+len(p)]][0]
Out[83]: 1
I have created a function which randomly generates a list of the letters "a", "b", "c", and "d". I would like to create a new list which is the same as the first list but with any letters/items which are the same as the previous letter/item removed. Where I am having problems is referring to the previous letter in the list.
For example, if :
letterlist = ['a','a','a','b','b','a,',b']
then the output should be,
nondupelist = ['a','b','a','b']
The problem is that nodupeletterlist is the same as letterlist - meaning it's not removing items which are the same as the last - because I am getting the function to refer to the previous item in letterlist wrong. I have tried using index and enumerate, but I am obviously using them wrong because I'm not getting the correct results. Below is my current attempt.
import random
def rdmlist(letterlist, nodupeletterlist):
for item in range(20):
rng = random.random()
if rng < 0.25:
letterlist.append("a")
elif 0.25 <= rng and rng < 0.5:
letterlist.append("b")
elif 0.5 <= rng and rng < 0.75:
letterlist.append("c")
else:
letterlist.append("d")
for letter in letterlist:
if letter != letterlist[letterlist.index(letter)-1]:
nodupeletterlist.append(letter)
else:
pass
return
letterlist1 = []
nodupeletterlist1 = []
rdmlist(letterlist1, nodupeletterlist1)
EDIT:
This is what I ended up using. I used this solution simply because I understand how it works. The answers below may provide more succinct or pythonic solutions.
for index, letter in enumerate(letterlist, start=0):
if 0 == index:
nodupeletterlist.append(letter)
else:
pass
for index, letter in enumerate(letterlist[1:], start = 1):
if letter != letterlist[index-1]:
nodupeletterlist.append(letter)
else:
pass
for i, letter in enumerate(([None]+letterlist)[1:], 1):
if letter != letterlist[i-1]:
nodupeletterlist.append(letter)
You can use itertools.groupby:
import itertools
nodupeletterlist = [k for k, _ in itertools.groupby(letterlist)]
Solution without using itertools, as requested in the comments:
def nodupe(letters):
if not letters:
return []
r = [letters[0]]
for ch in letters[1:]:
if ch != r[-1]:
r.append(ch)
return r
nodupeletterlist = nodupe(letterlist)
A fixed version of the proposed "working solution":
def nodupe(letters):
if not letters:
return []
r = [letters[0]]
r += [l for i, l in enumerate(letters[1:]) if l != letters[i]]
return r
nodupeletterlist = nodupe(letterlist)
You can also simplify your random generator a bit, by using random.choices:
import random
chars = 'abcd'
letterlist = random.choices(chars, k=20)
or by using random.randint:
import random
start, end = ord('a'), ord('d')
letterlist = [chr(random.randint(start, end)) for _ in range(20)]
Here's what I came up with. Using random.choices() would be better than what I have below, but same idea. doesn't involve itertools
>>> li_1 = [random.choice("abcdefg") for i in range(20)]
>>> li_1
['c', 'e', 'e', 'g', 'b', 'd', 'b', 'g', 'd', 'c', 'e', 'g', 'e', 'c', 'd',
'e', 'e', 'f', 'd', 'd']
>>>
>>> li_2 = [li_1[i] for i in range(len(li_1))
... if not i or i and li_1[i - 1] != li_1[i]]
>>> li_2
['c', 'e', 'g', 'b', 'd', 'b', 'g', 'd', 'c', 'e', 'g', 'e', 'c',
'd', 'e', 'f', 'd']
The problem with the way that you are using letterlist.index(letter)-1 is that list.index(arg) returns the the index of the first occurrence of arg in list, in this case the letter. This means that if you have list = ["a", "b", "a"] and you run list.index("a") it will always return 0.
A way to do what you intend to (removing consecutive repetitions of letters) would be:
nodupeletterlist.append(letterlist[0])
for idx in range(1, len(letterlist)):
if letterlist[idx] != letterlist[idx-1]:
nodupeletterlist.append(letterlist[idx])
Do This:
L1 = ['a','a','a','b','b','c','d']
L2 = []
L2.append(L1[0])
for i in range(1,len(L1)):
if L1[i] != L1[i-1]:
L2.append(L1[i])
set() will create a set with only unique values,then the list() will convert it back to a a list containing values without any repetition.
I hope this helps...
I have a string say a = "awxxxyyw".
It should remove all the consecutive elements from the string and return me final string as "a".
ie in 1st iteration xxx seems to be consecutive, so remove xxx, then string becomes awyyw.
2nd iteration removes yy. string becomes aww.
3rd iteration remove ww. returns a
Here is my code.
Where I'm going wrong?
def func(string,pointer):
print pointer
for i in range(pointer,len(string)):
flag=0
temp = i
print temp,pointer
try:
while(string[i-1] == string[i]):
print string
i+= 1
flag = 1
except : break
if flag == 0 :
continue
else:
string = string[0:temp] + string[i+1:len(string)]
func(string, temp)
return string
string = "awxxxyyw"
print func(string,1)
The problem with your code is that you’re only ever removing one character at a time, and so repeated sequences will be reduced to a single character, but that single character will stick around at the end. For example, your code goes from “xxx” to “xx” to “x”, but since there’s only a single “x” left that “x” is not removed from the string. Adapt your code to remove all of the consecutive repeated characters and your problem will be fixed.
I think this is easiest to do with an iterated regular expression substitution:
def remove_dups(s):
import re
pat = re.compile(r"(.)\1+")
while True:
news = pat.sub("", s)
if s == news:
break
s = news
return s
print remove_dups("awxxxyyw") # "a"
print remove_dups("aaxyyza") # "xza"
You need to modify your code to remove all consecutive repeated letters, rather than one at a time. Retaining your recursion:
def func(string):
for i in range(len(string) - 1):
if string[i] == string[i+1]:
j = i + 1
while j < len(string) and string[j] == string[i]:
j += 1
return func(string[:i] + string[j:])
return string
You can do this using itertools.groupby, it allows you to group adjacent similar items:
from itertools import groupby
def solve(x):
while True:
lis = [list(g) for k, g in groupby(x)]
print lis
#if any item in lis has length != 1 then remove all such items
if any(len(x) != 1 for x in lis):
x = ''.join([''.join(x) for x in lis if len(x)==1])
else:
return ''.join([''.join(x) for x in lis])
s = "awxxxyyw"
print solve(s)
print
s = 'aaacccxxxka'
print solve(s)
Output:
[['a'], ['w'], ['x', 'x', 'x'], ['y', 'y'], ['w']] #remove ['x', 'x', 'x'], ['y', 'y'] here
[['a'], ['w', 'w']] #remove ['w', 'w'] here
[['a']] #nothing to remove, returns this as answer.
a
[['a', 'a', 'a'], ['c', 'c', 'c'], ['x', 'x', 'x'], ['k'], ['a']]
[['k'], ['a']]
ka
A working demo:
def func(s):
stack = ['']
idx = 0
while idx < len(s):
if s[idx] == stack[-1]:
el = s[idx]
stack.pop()
while idx < len(s) and s[idx] == el:
idx += 1
else:
stack.append(s[idx])
idx += 1
return ''.join(stack)
print func('awxxxyyw')
'a'
print func('awxyw')
'awxyw'
print func('a')
'a'
print func('abcdefghijklmnoprstuvxywzzwyxvutsrponmlkjihgfedcba')
''
myList = [ 4,'a', 'b', 'c', 1 'd', 3]
how to split this list into two list that one contains strings and other contains integers in elegant/pythonic way?
output:
myStrList = [ 'a', 'b', 'c', 'd' ]
myIntList = [ 4, 1, 3 ]
NOTE: didn't implemented such a list, just thought about how to find an elegant answer (is there any?) to such a problem.
As others have mentioned in the comments, you should really start thinking about how you can get rid of the list which holds in-homogeneous data in the first place. However, if that really can't be done, I'd use a defaultdict:
from collections import defaultdict
d = defaultdict(list)
for x in myList:
d[type(x)].append(x)
print d[int]
print d[str]
You can use list comprehension: -
>>> myList = [ 4,'a', 'b', 'c', 1, 'd', 3]
>>> myIntList = [x for x in myList if isinstance(x, int)]
>>> myIntList
[4, 1, 3]
>>> myStrList = [x for x in myList if isinstance(x, str)]
>>> myStrList
['a', 'b', 'c', 'd']
def filter_by_type(list_to_test, type_of):
return [n for n in list_to_test if isinstance(n, type_of)]
myList = [ 4,'a', 'b', 'c', 1, 'd', 3]
nums = filter_by_type(myList,int)
strs = filter_by_type(myList,str)
print nums, strs
>>>[4, 1, 3] ['a', 'b', 'c', 'd']
Split the list according to types found in the orginal list
myList = [ 4,'a', 'b', 'c', 1, 'd', 3]
types = set([type(item) for item in myList])
ret = {}
for typeT in set(types):
ret[typeT] = [item for item in myList if type(item) == typeT]
>>> ret
{<type 'str'>: ['a', 'b', 'c', 'd'], <type 'int'>: [4, 1, 3]}
I'm going to summarize this thread by answering a Python FAQ "how do you write a method that takes arguments in any order, of a narrow range of types?"
Assuming the left-to-right order of all the arguments are not important, try this (based on #mgilson 's answer):
def partition_by_type(args, *types):
d = defaultdict(list)
for x in args:
d[type(x)].append(x)
return [ d[t] for t in types ]
def cook(*args):
commands, ranges = partition_by_type(args, str, range)
for range in ranges:
for command in commands:
blah blah blah...
Now you can call cook('string', 'string', range(..), range(..), range(..)). The argument order is stable, within its type.
# TODO make the strings collect the ranges, preserving order
you can use this code as an example to create two different lists by using the function isdigit(),which checks for integers in a string.
ip=['a',1,2,3]
m=[]
n=[]
for x in range(0,len(ip):
if str(ip[x]).isdigit():
m.append(ip[x])
else:n.append(ip[x])
print(m,n)
n = (input("Enter string and digits: "))
d=[]
s=[]
for x in range(0,len(n)):
if str(n[x]).isdigit():
d.append(n[x])
else
s.append(n[x])
print(d)
print(s)
Edit 1: Here is another solution
import re
x = input("Enter any string that contains characters and integers: ")
s = re.findall('[0-9]',x)
print(s)
c = re.findall('[a-z/A-Z]',x)
print(c)
myList = [ 4,'a', 'b', 'c', 1 'd', 3]
myList_string = []
myList_number = []
for a in myList:
if type(a) == int or type(a) == float:
myList_number.append(a)
elif type(a) == str:
myList_string.append(a)
import strings;
num=strings.digits;
str=strings.letters;
num_list=list()
str_list=list()
for i in myList:
if i in num:
num_list.append(int(i))
else:
str_list.append(i)