Na forum 4programmers.net korzystamy z plików cookies. Część z nich jest niezbędna do funkcjonowania
naszego forum, natomiast wykorzystanie pozostałych zależy od Twojej dobrowolnej zgody, którą możesz
wyrazić poniżej. Klikając „Zaakceptuj Wszystkie” zgadzasz się na wykorzystywanie przez nas plików cookies
analitycznych oraz reklamowych, jeżeli nie chcesz udzielić nam swojej zgody kliknij „Tylko niezbędne”.
Możesz także wyrazić swoją zgodę odrębnie dla plików cookies analitycznych lub reklamowych. W tym celu
ustaw odpowiednio pola wyboru i kliknij „Zaakceptuj Zaznaczone”. Więcej informacji o technologii cookie
znajduje się w naszej polityce prywatności.
Chodzi o to, że tylko raz występuje np.USDTBTC, więc chce to usunąć. Jeśli w tych zbiorach jest więcej niż 2 takie same wartości to zostawiam, jeśli jest tylko jedna na wszystkie zbiory to usuwam. Jak to zrobić? Pozdrawiam
import collections
c = collections.Counter()
with open('your_file.txt', 'r') as f:
c.update(f)
c będzie kontenerem (dictem) który zawiera informacje co ile razy występuje. Wyrzuć wszystko co występuje tylko raz i zostaw jako set(liczniki już nie potrzebne):
Kopiuj
c_filtered = {x for x in c if c[x] > 1}
Następnie możesz przeglądać swój zbiór raz jeszcze i akceptować tylko te, które są w c_filtered:
Kopiuj
for item in container:
if item not in c_filtered:
continue
#do whatever
Pisane z palca więc mogą być błędy w składni i logice ;)
data_sets = [['NULSBNB', 'BNBBTC','NULSBTC', 'NEOBTC', 'NULSETH', 'LINKBTC', 'IOTABTC', 'ETCBTC'], ['NULSBTC','NEOBTC','NULSETH','LINKBTC','IOTABTC','ETCBTC'],
['NULSBNB','BNBBTC','LINKBTC','IOTABTC','USDTBTC']]
def get_logest_set(data_sets):
longes_set_idx = 0
max_set = 0
for idx, item in enumerate(data_sets):
if len(item) > max_set:
longes_set_idx = idx
max_set = len(item)
return longes_set_idx
def create_template(logest_set):
tmp = {}
for item in logest_set:
if item not in tmp.keys():
tmp[item] = 1
else:
tmp[item] += 1
return tmp
logest_data_set = get_logest_set(data_sets)
template = create_template(data_sets[logest_data_set])
data_cp = data_sets[:]
data_cp.pop(logest_data_set)
to_delete = []
for item in data_cp:
for i in item:
if i in template.keys():
template[i] += 1
else:
template[i] = 1
for k, v in template.items():
if v < 2:
to_delete.append(k)
for idx, item in enumerate(data_sets):
for i, data in enumerate(item):
if item in to_delete:
data_sets[idx].pop(i)
print(data_sets)
Tu masz baaaardzo po kolei tak dla zrozumienia jak co sie dzieje :)
Zakładając że chcesz to przechowywać w pliku w formie tekstowej, nie istnieje w pojęciu pliku coś takiego jak usuwanie jego treści, tylko nadpisanie go nową wersją bez fragmentów które są nam zbędne. Zakładając że będziesz robił to częściej i jesteś na etapie który jeszcze nie zaburzy całej pracy programu, lepiej zapisać strukturę w formacie JSON, albo za pomocą pickle.
Gdybyś stworzył strukturę z Flagami bitowymi, każda flaga odpowiada innemu 'plikowi', możesz selektywnie sobie wybierać te które znajdują się w chociaż dwóch plikach, suma flag bitowych w takich warunkach będzie większa od dwóch i różna od czterech. Wczytanie struktury, będzie efektywniejsze od parsowania pliku, zliczania elementów i tworzenia struktury liczącej za każdym razem. Równie szybko możesz odfiltrować te które potrzebujesz.
Jeśli nie możesz tego już zmienić, i chcesz po prostu usuwać pojedyńcze rekordy ze zbioru plików, to @AsterFV podał dość dobry sposób z jednym wyjątkiem, załóżmy że z każdego pliku chcemy 'usunąć' pojedyńcze wystąpienie, musimy więc wiedzieć w których plikach są pozostałe rekordy.
Najprostsze rozwiązanie jakie ja widzę:
Kopiuj
defremove_unique_lines(filenames):
files_container ={}for filename in filenames:withopen(filename,"r")as f:
files_container[filename]= f.read()for filename, text in files_container.items():withopen(filename,"w")as f:for line in text:if count_from_iterable(files_container.values(), line)>1:
f.write(line)defcount_from_iterable(iter, search):
counter =0for elem initer:
counter += elem.count(search)return counter
if __name__ =="__main__":
filenames =("1.txt","2.txt","3.txt")
remove_unique_lines(filenames)
Mogłem się gdzieś machnąć, ale mniej więcej podobnie do tego mogłoby to wyglądać :)
Da się to zrobić optymalniej:
-Nie przeszukiwać tekstu z którego bierzesz te linię.
Albo jeszcze lepiej:
-Zastosować counter jak kolega wyżej ale zapamiętując pliki które trzeba później przelecieć, a później tylko wyszukiwać ile razy w counterze znajduje się linia, wtedy ją zapisać lub nie zależnie od ilości wystąpień...