How to create a dictionary using a single list?

You can do it like this:

>>> y = ['URL4','news1','news2','URL5','URL6','news1']
>>> result = {}
>>> current_url = None
>>> for entry in y:
...     if entry.startswith('URL'):
...         current_url = entry
...         result[current_url] = ()
...     else:
...         result[current_url] += (entry, )
...         
>>> result
{'URL4': ('news1', 'news2'), 'URL5': (), 'URL6': ('news1',)}

You can just use the indices of the URL keys in the list and grab what is between the indices and assign to the first

Like this:

x = ['URL1','news1','news2','news3','URL2','news1','news2','URL3','news1']
urls = [x.index(y) for y in x if 'URL' in y]
adict = {}
for i in range(0, len(urls)):
    if i == len(urls)-1:
        adict[x[urls[i]]] = x[urls[i]+1:len(x)]
    else:
        adict[x[urls[i]]] = x[urls[i]+1:urls[i+1]]
print(adict)

output:

{'URL1': ['news1', 'news2', 'news3'], 'URL2': ['news1', 'news2'], 'URL3': ['news1']}

You can use itertools.groupby with a key function to identify a URL:

from itertools import groupby
def _key(url):
    return url.startswith("URL") #in the body of _key, write code to identify a URL

data = ['URL1','news1','news2','news3','URL2','news1','news2','URL3','news1', 'URL4','news1','news2','URL5','URL6','news1']
new_d = [list(b) for _, b in groupby(data, key=_key)]
grouped = [[new_d[i], tuple(new_d[i+1])] for i in range(0, len(new_d), 2)]
result = dict([i for [*c, a], b in grouped for i in [(i, ()) for i in c]+[(a, b)]])

Output:

{
 'URL1': ('news1', 'news2', 'news3'), 
 'URL2': ('news1', 'news2'), 
 'URL3': ('news1',), 
 'URL4': ('news1', 'news2'), 
 'URL5': (), 
 'URL6': ('news1',)
}

The more-itertools library contains a function split_before() which comes in very handy for this purpose:

{s[0]: tuple(s[1:]) for s in mt.split_before(x, lambda e: e.startswith('URL'))}

I think this is cleaner than any of the other approaches in answers posted before this one, but it does introduce an external dependency (unless you reimplement the function), which makes it not appropriate for every situation.

If your actual use case involves real URLs or something else, rather than strings of the form URL#, then just replace lambda e: e.startswith('URL') with whatever function you can use to select the key elements apart from the value elements.