0

I have the set

set1={'*klj?', 'bl:VOLTe?', 'abkjld:Sure:STe?', 'JKLJS?', 'TRered[:AMide]?', 'DKJ[:dkja]?'}

I want to have the set look like

set1={'*klj?', 'bl:VOLTe?', 'abkjld:Sure:STe?', 'JKLJS?', 'TRered?','DKJ?'}

where I want to get rid of the [:AMide] and [:dkja] inside the set.

I was trying to use regex

What I have so far is

set2={}
    for element in set:
        x=re.sub("([\(\[]).*?([\)\]])", "", str(element))
        set2.add(x)

This gets rid of the [] and what is inside but doesn't properly recreate the set, ie set2.add(x) doesn't work

Bob
  • 279
  • 6
  • 13
  • This seems like a very simple `re.sub()`. What problem are you having? – Barmar Feb 16 '18 at 21:06
  • Replace with an empty string, replace `"\g<1>\g<2>"` with `""` – Wiktor Stribiżew Feb 16 '18 at 21:08
  • Hi @wiktor Stribizew , thank you! I am going to edit my question above that incorporates your comment – Bob Feb 16 '18 at 21:11
  • No need to, I'd rather remove this question. You should just use http://regex101.com to see what the regex does and also read the `re` documentation regarding `re.sub` and especially - backreferences. – Wiktor Stribiżew Feb 16 '18 at 21:12
  • The main focus of my question wasn't about understanding that line, that was a part of the question. – Bob Feb 16 '18 at 21:16
  • I guess your problem is adding the items to a set (and you defined dictionaries with `{}`, using `{}` creates an empty dict). Also, note that `for element in set:` refers to `set`, and you only have `set1` with data. – Wiktor Stribiżew Feb 16 '18 at 21:22
  • The answer is https://ideone.com/TDj4Er, your question is a dupe of https://stackoverflow.com/questions/17373161/using-curly-braces-to-initialize-set – Wiktor Stribiżew Feb 16 '18 at 21:27
  • @Barmar I believe the question is a dupe of https://stackoverflow.com/questions/17373161/using-curly-braces-to-initialize-set, please check and if you agree please re-close. – Wiktor Stribiżew Feb 16 '18 at 21:28
  • What do you mean that `set2.add(x)` doesn't work? Do you get any error? – Mazdak Feb 16 '18 at 21:29
  • @Kasramvd Have you seen my comments? Yes, there is an error, `AttributeError: 'dict' object has no attribute 'add'` – Wiktor Stribiżew Feb 16 '18 at 21:31
  • @WiktorStribiżew I don't think so. The question isn't about how to create the initial set, it's about how to modify elements of a set. – Barmar Feb 16 '18 at 21:31
  • @Barmar Shall I post my answer then? https://ideone.com/TDj4Er? – Wiktor Stribiżew Feb 16 '18 at 21:31
  • If it's about the correct syntax for creating a set, I think it should just be a comment. – Barmar Feb 16 '18 at 21:32
  • @Barmar But it is the only real error left. The regex has been fixed after my comment. So, two comments answer the question, that is kind of weird. – Wiktor Stribiżew Feb 16 '18 at 21:32
  • I guess he's changed the question.... – Barmar Feb 16 '18 at 21:34
  • He does that all the time, starting with yesterday. – Wiktor Stribiżew Feb 16 '18 at 21:34
  • @WiktorStribiżew Indeed, I'd like to let him to see it by himself. It seems that OP hasn't read the traceback before asking the question and is asking a wrong question. Like always in SO you should teach how to ask before addressing the actual problem. – Mazdak Feb 16 '18 at 21:35

4 Answers4

1

You don't need such a complicated regex for this task. Just use two replaces with a set-comprehension:

In [10]: {i.replace('[:AMide]', '').replace('[:dkja]', '') for i in set1}
Out[10]: {'*klj?', 'DKJ?', 'JKLJS?', 'TRered?', 'abkjld:Sure:STe?', 'bl:VOLTe?'}

After all, if you want to remove everything between brackets I think you could simply use a negated character class as following:

In [11]: import re

In [12]: {re.sub(r'\[[^]]+\]', r'', i) for i in set1}
Out[12]: {'*klj?', 'DKJ?', 'JKLJS?', 'TRered?', 'abkjld:Sure:STe?', 'bl:VOLTe?'}
Mazdak
  • 105,000
  • 18
  • 159
  • 188
  • 1
    I think he wants to get rid of any `[...]`, not just those specific strings. – Barmar Feb 16 '18 at 21:12
  • @Barmar Well, that has nothing to do with this question. Plus I don't see if OP is mentioned any other cases. – Mazdak Feb 16 '18 at 21:15
  • It became more obvious when he added his attempted code. – Barmar Feb 16 '18 at 21:16
  • @Barmar No it won't because still looks like an XY problem. – Mazdak Feb 16 '18 at 21:25
  • @Kasramvd I was going to change the close reason to https://stackoverflow.com/questions/17373161/using-curly-braces-to-initialize-set, please close as a dupe. Bob initialized a dictionary, not a set, with `{}`. Here is an answer - https://ideone.com/TDj4Er – Wiktor Stribiżew Feb 16 '18 at 21:26
  • @WiktorStribiżew That's not even close to the question. I search for a duplicated already and couldn't find one that satisfies both the Regex and set side. – Mazdak Feb 16 '18 at 21:31
1

Strings are immutable. You can not replace a string in-place. The proper way to modify your set is either to remove the offending elements and put in the correct versions, or to create an entirely new set. The latter approach is a one-liner:

set1 = set(re.sub("([\(\[]).*?([\)\]])", "\g<1>\g<2>", str(element)) for element in set1)
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
0

You can try this:

import re
set1={'*klj?', 'bl:VOLTe?', 'abkjld:Sure:STe?', 'JKLJS?', 'TRered[:AMide]?', 'DKJ[:dkja]?'}
new_set = {re.sub('\[\:[a-zA-Z]+\]', '', i) for i in set1}

Output:

{'*klj?', 'abkjld:Sure:STe?', 'DKJ?', 'JKLJS?', 'TRered?', 'bl:VOLTe?'}
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
0

Here is another option

res = {re.sub('(:AMide)|(:dkja)', '', s) for s in set1}
{re.sub(']|\[', '', t) for t in res}

The output is:

>>>>  {'*klj?', 'DKJ?', 'JKLJS?', 'TRered?', 'abkjld:Sure:STe?', 'bl:VOLTe?'}
Samuel Nde
  • 2,565
  • 2
  • 23
  • 23