how to un-append an appended variable - python

How would I unappend these appended variable:
if letterchoice == wordchoice[0]:
wc = []
for each in wordchoice:
wc.append(each)
wh = []
for each in wordhidden:
wh.append(each)
wh[0] = wc[0]
This is for part of a hangman program(I understand that this is probably not the most efficient way of doing this but I am new to python and wanted to give myself a challenge)

There are several ways you can remove item from a list, you can delete by the value or by the index:
>>> foo = [1,2,3,4]
>>> foo.pop(1)
2
>>> foo
[1, 3, 4]
>>> foo.remove(1)
>>> foo
[3, 4]
>>> del foo[1]
>>> foo
[3]
>>>
Nevertheless, I suggest to use .pop().
Edit: Based on your comment, is this what you want to do?
>>> foo = ['h', 'm', 'f', 'd', 's']
>>> foo
['h', 'm', 'f', 'd', 's']
>>> ''.join(foo)
'hmfds'
>>>

Use the python list pop() method, which removes and returns last object or obj from the list i.e.
wh.pop()
To avoid popping from an empty list, consider checking first:
if wh: # Makes sure there is something to pop()
wh.pop()
Also, you may want to "catch" the popped entry and avoid it from being printed to the terminal, as in:
if wh:
x = wh.pop()

Related

I don't how this list slicing works, can anybody explain?

I have this code in python:
string_a = "abcdef"
list_a = []
list_a[:0] = string_a
and it outputs ["a","b","c","d","e","f"] and although this is exactly what I want I don't understand how it worked. this [:0] basically means that we start from the beginning of the list and stop at the beginning, we have an empty list. After that we assign the value of the string to the empty list and then I don't understand what happens anymore.
How did the string got split into a list of single characters?
As #Barmar explained in the comments, all elements from the iterable on the right hand side of the assignment are inserted, and the list grows as necessary.
It's probably clearer with these examples:
stop != start
>>> l = [0, 1, 2, 3]
>>> l[1:2] = 'abc'
>>> l
[0, 'a', 'b', 'c', 2, 3]
stop = start
>>> l = [0, 1, 2, 3]
>>> l[1:1] = 'abc'
>> l
[0, 'a', 'b', 'c', 1, 2, 3]
what you're doing is you're replacing that segment of the "list_a" with whatever value you give it.
for example:
string_a = "abcdef"
list_a = []
list_a[:0] = string_a
>> list_a
>> ['a', 'b', 'c', 'd', 'e', 'f']
>> list_a[:3] = "123"
>> list_a
>> ['1', '2', '3', 'd', 'e', 'f']

Python Collection Counter subtract versus '-'

I'm new to pythonic style solutions, and I'm trying to understand how to read the following code, or understand what actually happens
given:
s = "bab"
t = "aba"
s_counter = Counter(s) # Counter({'b': 2, 'a': 1})
t_counter = Counter(t) # Counter({'a': 2, 'b': 1})
what's the difference between
print((s_counter - t_counter)) # Counter({'b': 1})
versus
s_counter.subtract(t_counter)
print(s_counter) # Counter({'b': 1, 'a': -1})
and what actually happen when you run that code?
on subtract() function it seems like it basically grab each key and find subtract s_counter value with t_counter value.
but I'm not sure with
print((s_counter - t_counter))
The .subtract method works in-place on a Counter object, and accepts mappings (e.g. dict or Counters) or arbitrary iterables. Also, it allows for non-positive values.
The - operator creates a new counter object, and will only contain the positive results (0's and negative values are ignored in the result). It only works between Counter objects.
An analogous relationship exists between the .update method and the + operator.
Just to add on juanpa.arrivillaga's excellent explanations, here's some output to help understand difference.
With following example:
>>> from collections import Counter
>>> counter_a = Counter("some random message")
>>> counter_b = Counter("even more random message")
If we check id of instances - which is unique for each instance - you'll see it's different, so essentially a new instance is created when you use operators.
>>> id(counter_a)
2507556487952
>>> id(counter_b)
2507555822864
# Different id
>>> id(counter_a - counter_b)
2507537937808
# resulting instance is not a same instance as counter_a
>>> counter_a is (counter_a - counter_b)
False
So there's the main difference, when new instance is created, original instances aren't affected. If original instance is modified, it usually doesn't return anything.
This theme goes in built-in python collections like set, list, etc.
>>> set_a = set("abcde")
>>> set_b = set("cdefg")
# not same instance
>>> set_a is set_a - set_b
False
# original didn't get affected
>>> set_a
{'c', 'a', 'd', 'b', 'e'}
# returns nothing
>>> set_a.difference_update(set_b)
# this time it's affected
set_a
{'a', 'b'}
>>> list_a = list("abcde")
>>> list_b = list("cdefg")
# not same instance
>>> list_a is list_a + list_b
False
# not affected
>>> list_a
['a', 'b', 'c', 'd', 'e']
# returns nothing
>>> list_a.extend(list_b)
# now affected
>>> list_a
['a', 'b', 'c', 'd', 'e', 'c', 'd', 'e', 'f', 'g']

How to change list of tuples to same tuples? [python]

I have list like this:
l = [("a"), ("b"), ("c")]
and i need to have:
l = ("a"), ("b"), ("c")
Someone know some reasonable quick way to do this?
You said you have a list of tuples. What you've shown isn't actually a list of tuples. It's a list of strings:
>>> [("a"), ("b"), ("c")]
['a', 'b', 'c']
>>> type(("a"))
<class 'str'>
I think what you meant was l = [("a",), ("b",), ("c",)]. That's a list of tuples.
To change your list of tuples into a tuple of tuples, you simply do:
>>> tuple(l)
(('a',), ('b',), ('c',))
EDIT - Note, that the following literal syntax:
l = ("a",), ("b",), ("c",)
Is a tuple of tuples.
You say you want
>>> want = ("a"), ("b"), ("c")
>>> want
('a', 'b', 'c')
You say you have
>>> have = [("a"), ("b"), ("c")]
>>> have
['a', 'b', 'c']
Use tuple() to get what you want from what you have:
>>> tuple(have)
('a', 'b', 'c')
>>> tuple(have) == want
True
If you want to make a list of strings to a tuple of strings simply use tuple()
>>> l = [("a"), ("b"), ("c")]
>>> l
['a', 'b', 'c']
>>>
>>> tuple(l)
('a', 'b', 'c')
Is this what you mean?
l = [(1,2),(2,3),(3,4)]
a,b,c = l
# now a = (1,2), b = (2,3), c = (3,4)
Otherwise the other answers should be able to help you. You might also want to look into the * operator ("unpacks" a list, so e.g. [*l,(4,5)] == [(1,2),(2,3),(3,4),(4,5)]) as well.
Either way, you might want to improve your phrasing for any other question you intend to post. Give concrete examples of what you want, what you tried and what (unintended) effects that had.

Removing a string from a list

I create a list, and I want to remove a string from it.
Ex:
>>> myList = ['a', 'b', 'c', 'd']
>>> myList = myList.remove('c')
>>> print(myList)
None
What am I doing wrong here? All I want is 'c' to be removed from myList!
I am not sure what a is (I am guessing another list), you should do myList.remove() alone, without assignment.
Example -
>>> myList = ['a', 'b', 'c', 'd']
>>> myList.remove('c')
>>> myList
['a', 'b', 'd']
myList.remove() does not return anything, hence when you do myList = <anotherList>.remove(<something>) it sets myList to None
Remember that lists are mutable, so you can simply call remove on the list itself:
>>> myList = ['a', 'b', 'c', 'd']
>>> myList.remove('c')
>>> myList
['a', 'b', 'd']
The reason you were getting None before is because remove() always returns None
Just an addition to Anand's Answer,
mylist = mylist.remove('c')
The above code will return 'none' as the return type for my list. So you want to keep it as
mylist.remove('c')
The remove() function doesn't return anything, it modifies the list in place. If you don't assign it to a variable you will see that myList doesn't contain c anymore.

In-place function to remove an item using index in Python [duplicate]

This question already has answers here:
A quick way to return list without a specific element in Python
(9 answers)
Closed 5 months ago.
Just noticed that there is no function in Python to remove an item in a list by index, to be used while chaining.
For instance, I am looking for something like this:
another_list = list_of_items.remove[item-index]
instead of
del list_of_items[item_index]
Since, remove(item_in_list) returns the list after removing the item_in_list; I wonder why a similar function for index is left out. It seems very obvious and trivial to have been included, feels there is a reason to skip it.
Any thoughts on why such a function is unavailable?
----- EDIT -------
list_of_items.pop(item_at_index) is not suitable as it doesn't return the list without the specific item to remove, hence can't be used to chain. (As per the Docs: L.pop([index]) -> item -- remove and return item at index)
Here's a nice Pythonic way to do it using list comprehensions and enumerate (note that enumerate is zero-indexed):
>>> y = [3,4,5,6]
>>> [x for i, x in enumerate(y) if i != 1] # remove the second element
[3, 5, 6]
The advantage of this approach is that you can do several things at once:
>>> # remove the first and second elements
>>> [x for i, x in enumerate(y) if i != 0 and i != 1]
[5, 6]
>>> # remove the first element and all instances of 6
>>> [x for i, x in enumerate(y) if i != 0 and x != 6]
[4, 5]
Use list.pop:
>>> a = [1,2,3,4]
>>> a.pop(2)
3
>>> a
[1, 2, 4]
According to the documentation:
s.pop([i])
same as x = s[i]; del s[i]; return x
UPDATE
For chaining, you can use following trick. (using temporary sequence that contains the original list):
>>> a = [1,2,3,4]
>>> [a.pop(2), a][1] # Remove the 3rd element of a and 'return' a
[1, 2, 4]
>>> a # Notice that a is changed
[1, 2, 4]
To get the result of removing (i.e, a new list, not in-place) a single item by index, there is no reason to use enumerate or a list comprehension or any other manual, explicit iteration.
Instead, simply slice the list before and after, and put those pieces together. Thus:
def skipping(a_list, index):
return a_list[:index] + a_list[index+1:]
Let's test it:
>>> test = list('example')
>>> skipping(test, 0)
['x', 'a', 'm', 'p', 'l', 'e']
>>> skipping(test, 4)
['e', 'x', 'a', 'm', 'l', 'e']
>>> skipping(test, 6)
['e', 'x', 'a', 'm', 'p', 'l']
>>> skipping(test, 7)
['e', 'x', 'a', 'm', 'p', 'l', 'e']
>>> test
['e', 'x', 'a', 'm', 'p', 'l', 'e']
Notice that it does not complain about an out-of-bounds index, because slicing doesn't in general; this must be detected explicitly if you want an exception to be raised. If we want negative indices to work per Python's usual indexing rules, we also have to handle them specially, or at least -1 (it is left as an exercise to understand why).
Fixing those issues:
def skipping(a_list, index):
count = len(a_list)
if index < 0:
index += count
if not 0 <= index < count:
raise ValueError
return a_list[:index] + a_list[index+1:]
As Martijn Pieters noted in comments to the question, this is not implemented as: Python in-place operations, as a rule, return None, never the altered object.

Categories